Skip to content

Commit d2456c5

Browse files
fix(DatabasePagingSource): Refactor the class to deal with orderbyChild queries
I've implemented the solution provided in firebase#2000 originally in Kotlin. Co-Authored-By: Dario Elyasy <[email protected]>
1 parent 653be71 commit d2456c5

File tree

2 files changed

+63
-9
lines changed

2 files changed

+63
-9
lines changed

database/src/main/java/com/firebase/ui/database/paging/DatabasePagingOptions.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ public Builder<T> setQuery(@NonNull Query query,
9494
public Builder<T> setQuery(@NonNull Query query,
9595
@NonNull PagingConfig config,
9696
@NotNull SnapshotParser<T> parser) {
97-
final Pager<String, DataSnapshot> pager = new Pager<>(config,
97+
final Pager<Object, DataSnapshot> pager = new Pager<>(config,
9898
() -> new DatabasePagingSource(query));
9999
mData = PagingLiveData.cachedIn(PagingLiveData.getLiveData(pager),
100100
mOwner.getLifecycle());

database/src/main/java/com/firebase/ui/database/paging/DatabasePagingSource.java

+62-8
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
package com.firebase.ui.database.paging;
22

33
import android.annotation.SuppressLint;
4+
import android.util.Pair;
45

56
import com.google.android.gms.tasks.Task;
67
import com.google.android.gms.tasks.Tasks;
78
import com.google.firebase.database.DataSnapshot;
89
import com.google.firebase.database.DatabaseError;
910
import com.google.firebase.database.Query;
11+
import com.google.firebase.database.snapshot.Index;
1012

1113
import org.jetbrains.annotations.Nullable;
1214

@@ -21,7 +23,7 @@
2123
import io.reactivex.rxjava3.core.Single;
2224
import io.reactivex.rxjava3.schedulers.Schedulers;
2325

24-
public class DatabasePagingSource extends RxPagingSource<String, DataSnapshot> {
26+
public class DatabasePagingSource extends RxPagingSource<Object, DataSnapshot> {
2527
private final Query mQuery;
2628

2729
private static final String STATUS_DATABASE_NOT_FOUND = "DATA_NOT_FOUND";
@@ -32,18 +34,45 @@ public DatabasePagingSource(Query query) {
3234
this.mQuery = query;
3335
}
3436

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+
3550
/**
3651
* DatabaseError.fromStatus() is not meant to be public.
3752
*/
3853
@SuppressLint("RestrictedApi")
3954
@NonNull
4055
@Override
41-
public Single<LoadResult<String, DataSnapshot>> loadSingle(@NonNull LoadParams<String> params) {
56+
public Single<LoadResult<Object, DataSnapshot>> loadSingle(@NonNull LoadParams<Object> params) {
4257
Task<DataSnapshot> task;
58+
59+
Index queryChildPathIndex = mQuery.getSpec().getIndex();
60+
Pair<Object, String> pKey = (Pair<Object, String>) params.getKey();
61+
4362
if (params.getKey() == null) {
4463
task = mQuery.limitToFirst(params.getLoadSize()).get();
4564
} 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+
}
4776
}
4877

4978
return Single.fromCallable(() -> {
@@ -54,7 +83,7 @@ public Single<LoadResult<String, DataSnapshot>> loadSingle(@NonNull LoadParams<S
5483

5584
//Make List of DataSnapshot
5685
List<DataSnapshot> data = new ArrayList<>();
57-
String lastKey = null;
86+
Pair<Object, String> lastKey = null;
5887

5988
if (params.getKey() == null) {
6089
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
@@ -77,7 +106,14 @@ public Single<LoadResult<String, DataSnapshot>> loadSingle(@NonNull LoadParams<S
77106
//Detect End of Data
78107
if (!data.isEmpty()) {
79108
//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+
81117
}
82118
return toLoadResult(data, lastKey);
83119
} else {
@@ -99,9 +135,9 @@ public Single<LoadResult<String, DataSnapshot>> loadSingle(@NonNull LoadParams<S
99135
}).subscribeOn(Schedulers.io()).onErrorReturn(LoadResult.Error::new);
100136
}
101137

102-
private LoadResult<String, DataSnapshot> toLoadResult(
138+
private LoadResult<Object, DataSnapshot> toLoadResult(
103139
@NonNull List<DataSnapshot> snapshots,
104-
String nextPage
140+
Pair<Object, String> nextPage
105141
) {
106142
return new LoadResult.Page<>(
107143
snapshots,
@@ -111,6 +147,24 @@ private LoadResult<String, DataSnapshot> toLoadResult(
111147
LoadResult.Page.COUNT_UNDEFINED);
112148
}
113149

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+
114168
@Nullable
115169
private String getLastPageKey(@NonNull List<DataSnapshot> data) {
116170
if (data.isEmpty()) {
@@ -122,7 +176,7 @@ private String getLastPageKey(@NonNull List<DataSnapshot> data) {
122176

123177
@Nullable
124178
@Override
125-
public String getRefreshKey(@NonNull PagingState<String, DataSnapshot> state) {
179+
public String getRefreshKey(@NonNull PagingState<Object, DataSnapshot> state) {
126180
return null;
127181
}
128182
}

0 commit comments

Comments
 (0)