我正在尝试使用日期作为嵌套项在ref节点上调用oderByChild
。它说:
paymentIDs-> userIDXX1-> orderID-> date:“ 1254785xxxx”在返回NULL 在节点
onDatechange()
上也提供了paymentIDs
.indexOn:date
mFirebaseDatabase = FirebaseDatabase.getInstance();
Query listpayment = mFirebaseDatabase.getReference("paymentIDs").orderByChild("date").startAt(fromdateinLong).endAt(todateinLong);
listpayment.addListenerForSingleValueEvent(valueEventListener);
ValueEventListener valueEventListener = new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.e(TAG,"valueEventListener: OnDatachanged" );
if (dataSnapshot.exists()) {
//if not null, do something.
}
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
Log.e(TAG,"valueEventListener: OnCancelled" );
}
};
答案 0 :(得分:1)
You are getting null
because you are missing a child, which is the id of the user. To solve this, please change the following line of code:
Query listpayment = mFirebaseDatabase.getReference("paymentIDs").orderByChild("date").startAt(fromdateinLong).endAt(todateinLong);
to
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
Query listpayment = mFirebaseDatabase.getReference()
.child("paymentIDs")
.child(uid)
.orderByChild("date")
.startAt(fromdateinLong).endAt(todateinLong);
ValueEventListener valueEventListener = new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String userId = ds.child("userId").getValue(String.class);
Log.d(TAG, userId);
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
}
};
listpayment.addListenerForSingleValueEvent(valueEventListener);
Edit:
According to your comments, you should know that using this database schema you cannot get all payments under all users. In Firebase there is no way to use wildcards. So a query like this:
Query listpayment = mFirebaseDatabase.getReference()
.child("paymentIDs")
.child(?)
.orderByChild("date")
.startAt(fromdateinLong).endAt(todateinLong);
Is not allowed. To solve this, there is an workaround, which implies you to duplicate data. So you should create another node in which you should add all the payments of all users. This practice is called denormalization
and is a common practice when it comes to Firebase. For a better understanding, I recommend you see this video, Denormalization is normal with the Firebase Database.
Also, when you are duplicating data, there is one thing that need to keep in mind. In the same way you are adding data, you need to maintain it. With other words, if you want to update/detele an item, you need to do it in every place that it exists.
So unfortunately, using the actual database structure you cannot achieve what you want.