我在Firebase中具有以下结构:
我只想检索给定范围内的日期,为此,我使用了以下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);
子项下,我将小时除以例如- 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}
答案 0 :(得分:2)
您不应该使用查询来获取该密钥。如果要返回列表,或者不知道要尝试到达的确切路径,则使用查询。
您知道uid
和date
可以直接查询该对象。
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");
否则,如果要查询,则应使用startAt
或endAt
方法。
JavaScript:
getMealsRefForUser(userId, startDate) {
return firebase.database().ref(`/mealsOf/${userId}`).orderByKey().startAt(startDate);
}
Android:
return root.orderByKey().startAt("2018-11-17");