按值/键对Firebase和筛选进行排序

时间:2018-11-18 22:50:11

标签: android firebase firebase-realtime-database

我在Firebase中具有以下结构:

enter image description here

我只想检索给定范围内的日期,为此,我使用了以下return getMealsRefForUser().orderByValue().equalTo("2018-11-17");,其中引用为mealsRefForUser= firebaseDatabase.getReference(MEALS_OF).child(user.getUid());。 但是,过滤不会发生。我想念什么?

编辑:因此,即使我得到/mealsOf/<userId>的限制,我也总是得到orderByKey().startAt().endAt()节点,尽管我的目的是获得包含一堆节点的数据快照,这些节点的{{1 }}“标签”在给定范围内。

编辑:我想要实现的是将<year>-<month>-<day>绑定到这样的查询:

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()); } } }

我提供新的查询约束时未触发。这是否意味着我的应用程序每次运行只能获得一个viewmodelprovider?

编辑:在上面的更新图像中,在日期的viewModel= ViewModelProviders.of(this, new CustomViewModelFactory(c)) .get(MealListViewModel.class);子项下,我将小时除以例如- meals20等。如何限制两个轴(天和小时)的查询? 在我想知道(我必须承认适当的)重组我的数据库模式的注释之前,我想知道是否有可能。 我们需要遵循以下内容吗?

8PM

或者,我是否应该保留其他位置(如 return await dbroot.ref(`mealsOf/${userId}`) .orderByKey().startAt(dayFrom).endAt(dayTo) .orderByChild("meals") .startAt(`${hourFrom}:00`).endAt(`${hourTo}:59`) 来启用诸如

的查询
duplicate/{userId}/{day}/{hour}

1 个答案:

答案 0 :(得分:2)

您不应该使用查询来获取该密钥。如果要返回列表,或者不知道要尝试到达的确切路径,则使用查询。

您知道uiddate可以直接查询该对象。

JavaScript:

getMealsRefForUser(userId, date) {
  return firebase.database().ref(`/mealsOf/${userId}/${date}`);
}

Android:

DatabaseReference root = FirebaseDatabase.getInstance().getReference("mealsOf");
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
return root.child(uid).child("2018-11-17");

否则,如果要查询,则应使用startAtendAt方法。

JavaScript:

getMealsRefForUser(userId, startDate) {
  return firebase.database().ref(`/mealsOf/${userId}`).orderByKey().startAt(startDate);
}

Android:

return root.orderByKey().startAt("2018-11-17");