Firebase&Filtering按值/键排序
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Firebase&Filtering按值/键排序相关的知识,希望对你有一定的参考价值。
我在Firebase中有以下结构:
我想只检索属于给定范围内的日期,为此我使用以下return getMealsRefForUser().orderByValue().equalTo("2018-11-17");
,其中引用是mealsRefForUser= firebaseDatabase.getReference(MEALS_OF).child(user.getUid());
。但是,过滤不会发生。我错过了什么?
编辑:所以,我总是得到/mealsOf/<userId>
节点,即使我通过orderByKey().startAt().endAt()
限定它,虽然我的目标是获得包含一堆节点的数据快照,其中<year>-<month>-<day>
“tag”在给定范围内。
编辑:我想要实现的是将LiveData
绑定到这样的查询:
public FirebaseQueryLiveData( Constraints c ) {
if ( c == null )
this.query= FirebaseDatabase.getInstance()
.getReference("/mealsOf")
.child(FirebaseAuth.getInstance().getCurrentUser().getUid());
else
this.query= FirebaseDatabase.getInstance()
.getReference("/mealsOf")
.child(FirebaseAuth.getInstance().getCurrentUser().getUid())
.orderByKey().startAt(c.dayFrom).endAt(c.dayTo);
}
但是这最终给了我整个列表,完全相同 - 不管有什么限制。该类的完整源代码:
// https://firebase.googleblog.com/2017/12/using-android-architecture-components.html
public class FirebaseQueryLiveData extends LiveData<DataSnapshot> {
private static final String TAG = "FirebaseQueryLiveData";
private boolean listenerRemovePending= false;
private final Handler handler= new Handler();
private final Runnable removeListener= new Runnable() {
@Override
public void run() {
query.removeEventListener(listener);
listenerRemovePending= false;
}
};
private static final String LOG_TAG= "FirebaseQueryLiveData";
private final Query query;
private final InnerValueEventListener listener= new InnerValueEventListener();
public FirebaseQueryLiveData( Constraints c ) {
if ( c == null )
this.query= FirebaseDatabase.getInstance()
.getReference("/mealsOf")
.child(FirebaseAuth.getInstance().getCurrentUser().getUid());
else
this.query= FirebaseDatabase.getInstance()
.getReference("/mealsOf")
.child(FirebaseAuth.getInstance().getCurrentUser().getUid())
.orderByKey().startAt(c.dayFrom).endAt(c.dayTo);
}
public FirebaseQueryLiveData( DatabaseReference ref ) {
this.query= ref;
}
@Override
protected void onActive() {
//Log.d(LOG_TAG, "onActive");
if ( listenerRemovePending )
handler.removeCallbacks(removeListener);
else
query.addValueEventListener(listener);
listenerRemovePending= false ;
}
@Override
protected void onInactive() {
//Log.d(LOG_TAG, "onInactive");
handler.postDelayed(removeListener,2000);
listenerRemovePending= true ;
//query.removeEventListener(listener);
}
private class InnerValueEventListener implements ValueEventListener {
@Override
public void onDataChange( @NonNull DataSnapshot dataSnapshot ) {
setValue(dataSnapshot);
}
@Override
public void onCancelled( @NonNull DatabaseError databaseError ) {
Log.e(LOG_TAG, "Can not listen to query " + query,databaseError.toException());
}
}
}
我想我知道发生了什么。我的代码中有这篇文章:viewModel= ViewModelProviders.of(this, new CustomViewModelFactory(c))
.get(MealListViewModel.class);
当我提供新的查询约束时,它不会触发。这是否意味着我每次运行应用程序时只能获得一个viewmodelprovider?
编辑:在上面更新的图像中,在日期的meals
孩子下我按小时划分 - 例如20
是8PM
等。我如何限制我的查询来自两个轴 - 天和小时?在我听到(我必须承认适当的)评论我需要重构我的数据库架构之前,我想知道这是否可行。我们是否需要以下内容?
return await dbroot.ref(`mealsOf/${userId}`)
.orderByKey().startAt(dayFrom).endAt(dayTo)
.orderByChild("meals")
.startAt(`${hourFrom}:00`).endAt(`${hourTo}:59`)
或者,我应该保留另一个位置,如duplicate/{userId}/{day}/{hour}
,以启用查询,如
return await dbroot.ref(`duplicate/${userId}`)
.orderByKey().startAt(dayFrom).endAt(dayTo)
.orderByKey()
.startAt(`${hourFrom}:00`).endAt(`${hourTo}:59`)
您不应该使用查询来获取该密钥。如果要返回列表,或者如果您不知道要尝试访问的确切路径,则使用查询。
如您所知uid
和date
,您可以直接查询对象。
getMealsRefForUser(userId, date) {
return firebase.database().ref(`/mealsOf/${userId}/${date}`);
}
安卓:
DatabaseReference root = FirebaseDatabase.getInstance().getReference("mealsOf");
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
return root.child(uid).child("2018-11-17");
否则,如果要查询,则应使用startAt
或endAt
方法。
JavaScript的:
getMealsRefForUser(userId, startDate) {
return firebase.database().ref(`/mealsOf/${userId}`).orderByKey().startAt(startDate);
}
安卓:
return root.orderByKey().startAt("2018-11-17");
以上是关于Firebase&Filtering按值/键排序的主要内容,如果未能解决你的问题,请参考以下文章
Angular 4 Firebase angularfire 按值对列表进行排序
Obj-C,iOS,我如何按值而不是键排序,sortedArrayUsingSelector,目前@selector(compare:)]