0

I am developing a chat app and using firebase as a backend service. I use snapshot.exists() to check if a child is exists and do stuff. But Firebase return true even that child is not exist. Example : I have 2 users A and B, user A send a message to user B , when user B received that message and check if the message is exist, ofcourse Firebase return true. Then user B closes the app and user A delete the message on database, user B restart app and check again, but it still return true even user A deleted the message.

P/s : I am using Persistance mode

this the the Database struture

----Messages
    |---UserA
    |------UserB
    |---------MessageId
    |---UserB
    |------UserA
    |---------MessageId  

code to check exist (run on user B device )

             ROOT_REF.child("Messages").child("UserA").child(userB_Id).orderByKey().equalTo(messageId)
.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                if (dataSnapshot.exists()){
                    //do stuff
                }else {

                }
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        });


UPDATE

I change the code to

ROOT_REF.child("Messages").child("UserA").child(userB_Id).child(messageId)
.addListenerForSingleValueEvent(new ValueEventListener() {});


but it still has the data even I deleted it from database

UPDATE 2

also tried this code but it still return data and snapshot still exists

ROOT_REF.child("Messages").child("UserA").child(userB_Id).child(messageId).keepSynced(true);

ROOT_REF.child("Messages").child("UserA").child(userB_Id).child(messageId)
.addListenerForSingleValueEvent(new ValueEventListener() {

//after do stuff 

ROOT_REF.child("Messages").child("UserA").child(userB_Id).child(messageId).keepSynced(false);

});

FOR NOW I AM STILL GETTING STUCK , BUT I AM USING A TEMP SOLUTION THAT DOUBLE THE QUERY, THE FIRST QUERY WILL BE UNUSABLE, WE WILL GET THE DATA FROMM THE SECOND ONE QUERY

ROOT_REF.child("Messages").child("UserA").child(userB_Id).child(messageId)
.addListenerForSingleValueEvent(new ValueEventListener() {

// dont use the first one

 ROOT_REF.child("Messages").child("UserA").child(userB_Id).child(messageId)
.addListenerForSingleValueEvent(new ValueEventListener() {
//get data from the second one
});

});

FINAL UPDATE: May be it is not posible if I want to check data on someone else node in my app with that database structure. To make it, I need to attach keepsynced or add a listener on Messsages node and cached the lasted data, this is not convenient for almost app at all.

Trung Trần
  • 51
  • 1
  • 7
  • https://stackoverflow.com/questions/48190268/firebase-always-true-when-checking-if-data-exists – Adarsh Anurag Aug 10 '19 at 13:00
  • Note that `.orderByKey().equalTo(messageId)` is the same as `.child(messageId)`, except for the format in which the data is returned. – Frank van Puffelen Aug 10 '19 at 14:05
  • Aside from that: `addListenerForSingleValueEvent ` and disk persistence don't work well together. Using `addListenerForSingleValueEvent` will immediately return the value from the cache. See https://stackoverflow.com/a/34487195 – Frank van Puffelen Aug 10 '19 at 14:08
  • I used `KeepSynced` on the current user database node, not on the other users node. How can I check that child exist on the some users else node – Trung Trần Aug 10 '19 at 14:54

1 Answers1

1

Ensure that when UserA deletes the messageId message from the server, that both users copies of the message (Messages/UserA/UserB/messageId and Messages/UserB/UserA/messageId) are deleted.

In your question's code, you are performing a query, rather than a simple database lookup. When you use any of the orderBy functions, you will always get a snapshot object back that 'exists', but you must look at that returned snapshot's children because that's where the query's results are stored.

Documentation on working with lists

To summarize, to go through the results of a query,

In your case, this problem can be avoided (and optimized) by not using orderByKey() on this line:

ROOT_REF.child("Messages").child("UserA").child(userB_Id).orderByKey().equalTo(messageId).addListenerForSingleValueEvent(new ValueEventListener() {

and simplifying it to a basic database lookup where snapshot.exists() would work as you expect in your question:

ROOT_REF.child("Messages").child("UserA").child(userB_Id).child(messageId).addListenerForSingleValueEvent(new ValueEventListener() {
samthecodingman
  • 23,122
  • 4
  • 30
  • 54