1
1
package com .firebase .ui .database .paging ;
2
2
3
3
import android .annotation .SuppressLint ;
4
+ import android .util .Pair ;
4
5
5
6
import com .google .android .gms .tasks .Task ;
6
7
import com .google .android .gms .tasks .Tasks ;
7
8
import com .google .firebase .database .DataSnapshot ;
8
9
import com .google .firebase .database .DatabaseError ;
9
10
import com .google .firebase .database .Query ;
11
+ import com .google .firebase .database .snapshot .Index ;
10
12
11
13
import org .jetbrains .annotations .Nullable ;
12
14
21
23
import io .reactivex .rxjava3 .core .Single ;
22
24
import io .reactivex .rxjava3 .schedulers .Schedulers ;
23
25
24
- public class DatabasePagingSource extends RxPagingSource <String , DataSnapshot > {
26
+ public class DatabasePagingSource extends RxPagingSource <Object , DataSnapshot > {
25
27
private final Query mQuery ;
26
28
27
29
private static final String STATUS_DATABASE_NOT_FOUND = "DATA_NOT_FOUND" ;
@@ -32,18 +34,45 @@ public DatabasePagingSource(Query query) {
32
34
this .mQuery = query ;
33
35
}
34
36
37
+ public Query startAt_childvalue (Object startvalue , String keyvalue ) {
38
+ if (startvalue instanceof String )
39
+ return mQuery .startAt ((String ) startvalue , keyvalue );
40
+ else if (startvalue instanceof Boolean )
41
+ return mQuery .startAt ((Boolean ) startvalue , keyvalue );
42
+ else if (startvalue instanceof Double )
43
+ return mQuery .startAt ((Double ) startvalue , keyvalue );
44
+ else if (startvalue instanceof Long )
45
+ return mQuery .startAt (((Long ) startvalue ).doubleValue (), keyvalue );
46
+ else
47
+ return mQuery ;
48
+ }
49
+
35
50
/**
36
51
* DatabaseError.fromStatus() is not meant to be public.
37
52
*/
38
53
@ SuppressLint ("RestrictedApi" )
39
54
@ NonNull
40
55
@ Override
41
- public Single <LoadResult <String , DataSnapshot >> loadSingle (@ NonNull LoadParams <String > params ) {
56
+ public Single <LoadResult <Object , DataSnapshot >> loadSingle (@ NonNull LoadParams <Object > params ) {
42
57
Task <DataSnapshot > task ;
58
+
59
+ Index queryChildPathIndex = mQuery .getSpec ().getIndex ();
60
+ Pair <Object , String > pKey = (Pair <Object , String >) params .getKey ();
61
+
43
62
if (params .getKey () == null ) {
44
63
task = mQuery .limitToFirst (params .getLoadSize ()).get ();
45
64
} else {
46
- task = mQuery .startAt (null , params .getKey ()).limitToFirst (params .getLoadSize () + 1 ).get ();
65
+ //change mQuery.startAt at value if child index
66
+ //if not null then what we have here is orderByChild query
67
+ if (queryChildPathIndex != null ) {//orderByChild query mode
68
+ task = startAt_childvalue (pKey .first , pKey .second )
69
+ .limitToFirst (params .getLoadSize () + 1 )
70
+ .get ();
71
+ } else {
72
+ task = mQuery .startAt (null , pKey .second )
73
+ .limitToFirst (params .getLoadSize () + 1 )
74
+ .get ();
75
+ }
47
76
}
48
77
49
78
return Single .fromCallable (() -> {
@@ -54,7 +83,7 @@ public Single<LoadResult<String, DataSnapshot>> loadSingle(@NonNull LoadParams<S
54
83
55
84
//Make List of DataSnapshot
56
85
List <DataSnapshot > data = new ArrayList <>();
57
- String lastKey = null ;
86
+ Pair < Object , String > lastKey = null ;
58
87
59
88
if (params .getKey () == null ) {
60
89
for (DataSnapshot snapshot : dataSnapshot .getChildren ()) {
@@ -77,7 +106,14 @@ public Single<LoadResult<String, DataSnapshot>> loadSingle(@NonNull LoadParams<S
77
106
//Detect End of Data
78
107
if (!data .isEmpty ()) {
79
108
//Get Last Key
80
- lastKey = getLastPageKey (data );
109
+ Object lastkey_c = getLastPageChildKey (data , queryChildPathIndex );
110
+ String lastkey_k = getLastPageKey (data );
111
+ lastKey = (lastkey_c == null && lastkey_k == null )
112
+ ? null
113
+ : (lastkey_k == null ) ? new Pair <>(lastkey_c , "" ) : new Pair <>(
114
+ lastkey_c ,
115
+ lastkey_k );
116
+
81
117
}
82
118
return toLoadResult (data , lastKey );
83
119
} else {
@@ -99,9 +135,9 @@ public Single<LoadResult<String, DataSnapshot>> loadSingle(@NonNull LoadParams<S
99
135
}).subscribeOn (Schedulers .io ()).onErrorReturn (LoadResult .Error ::new );
100
136
}
101
137
102
- private LoadResult <String , DataSnapshot > toLoadResult (
138
+ private LoadResult <Object , DataSnapshot > toLoadResult (
103
139
@ NonNull List <DataSnapshot > snapshots ,
104
- String nextPage
140
+ Pair < Object , String > nextPage
105
141
) {
106
142
return new LoadResult .Page <>(
107
143
snapshots ,
@@ -111,6 +147,24 @@ private LoadResult<String, DataSnapshot> toLoadResult(
111
147
LoadResult .Page .COUNT_UNDEFINED );
112
148
}
113
149
150
+ @ SuppressLint ("RestrictedApi" )
151
+ private Object getLastPageChildKey (@ NonNull List <DataSnapshot > data , Index index ) {
152
+ if (index == null ) return null ;
153
+ if (data .isEmpty ()) {
154
+ return null ;
155
+ } else {
156
+ return getChildValue (data .get (data .size () - 1 ), index );
157
+ }
158
+ }
159
+
160
+ @ SuppressLint ("RestrictedApi" )
161
+ private Object getChildValue (DataSnapshot snapshot , Index index ) {
162
+ String keypath = index .getQueryDefinition ();
163
+ DataSnapshot data = snapshot .child (keypath );
164
+ if (!data .exists ()) return null ;
165
+ return data .getValue ();
166
+ }
167
+
114
168
@ Nullable
115
169
private String getLastPageKey (@ NonNull List <DataSnapshot > data ) {
116
170
if (data .isEmpty ()) {
@@ -122,7 +176,7 @@ private String getLastPageKey(@NonNull List<DataSnapshot> data) {
122
176
123
177
@ Nullable
124
178
@ Override
125
- public String getRefreshKey (@ NonNull PagingState <String , DataSnapshot > state ) {
179
+ public String getRefreshKey (@ NonNull PagingState <Object , DataSnapshot > state ) {
126
180
return null ;
127
181
}
128
182
}
0 commit comments