Firebase:参考节点上的OrderbyChild,在onDataChange中返回NULL快照

时间:2018-12-27 12:17:43

标签: java android firebase firebase-realtime-database

我正在尝试使用日期作为嵌套项在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" );
    }
};

enter image description here

1 个答案:

答案 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.