Arnav Vohra
Arnav Vohra

Reputation: 397

Understanding Firebase ValueEventListeners onDataChange()

So I went through the documentation about how to retrieve datain Firebase: https://firebase.google.com/docs/database/android/retrieve-data

In my firebase app I am retrieving the values using the addListenerForSingleValueEvent. Those values retrieved(here userIdKey) in the onDataChange method are used to make updates to some other places in the database.

What I have observed is that sometimes the updates are made everywhere except at 123 (refer the code below).

    DatabaseReference channelFollowersRef = mDatabase.child("followers").child(mKey);
    channelFollowersRef.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {

            for(DataSnapshot childSnapshot:dataSnapshot.getChildren()){
                String userIdKey=childSnapshot.getKey();
        /*123*/ delChannelMap.put("/user-subscriptions/" + userIdKey + "//" + mChannelKey,null);
            }

            delChannelMap.put("/channels/" + mChannelKey, null);
            delChannelMap.put("/user-channels/" + getUid() + "/" + mChannelKey, null);
            delChannelMap.put("/channels-notices/" + mChannelKey, null);
            delChannelMap.put("/channels-subChannels/" + mChannelKey, null);
            delChannelMap.put("/channels-subChannels-comments/" + mChannelKey, null);
            delChannelMap.put("/channel-followers/" + mChannelKey, null);

            mDatabase.updateChildren(delChannelMap, new DatabaseReference.CompletionListener() {
                @Override
                public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
                    Toast.makeText(ChannelDetailActivity.this, "Channel is now deleted.", Toast.LENGTH_SHORT).show();
                }
            });
        }
        @Override
        public void onCancelled(DatabaseError databaseError) {
        }
    });

How to solve this issue.

Also can someone elabrate on how onDataChange works , does it get called when all the values at the node are retrieved or 'some' of the data is retrieved ?

Should one use AsyncTask in such a scenario when retrieving data.

Upvotes: 0

Views: 636

Answers (2)

Frank van Puffelen
Frank van Puffelen

Reputation: 598728

Your code seems to delete fanned out data from many locations.

When you perform a multi-location update() such as this, the security rules for all nodes are checked before any of the changes are made. So (unless there is a bug in the way Firebase enforces these specific security rules), the disconnect can't be caused by security rules.

If your other nodes are updated, but /user-subscriptions/" + userIdKey + "//" + mChannelKey is not deleted, then you are likely not getting any children in dataSnapshot (and thus not passing them in delChannelMap). You'll want to run through the code in a debugger to verify that.

Whenever troubleshooting issues such as this, be sure to handle onCancelled(). It is the easiest way to get an indication of why an operation failed. Although I don't think it will execute here (after all, the write operation seems to succeed), I recommend you attach a completion callback to setValue:

ref.setValue("My new value", new DatabaseReference.CompletionListener() {
    public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
        throw databaseError.toException();
    }
});

Throwing an exception like this ensures that it will be very difficult to overlook such an error next time.

Upvotes: 1

Sahaj Rana
Sahaj Rana

Reputation: 2013

  1. onDataChange gives you all the underlying child nodes at a single time whenever there is a change in the child nodes.

  2. Firebase when retrieve data it uses a different thread to perform its task so no need of using AsyncTask.

  3. the problem in your code maybe due to this String userIdKey=childSnapshot.getKey();...where the childSnapshot.getKey(); is not firing the data u want.. You should check in LOGCAT if data is retrieved correctly.

If it is not clear yet please add Json Data of your database so that it could be easier to understand what is happening.

Upvotes: 2

Related Questions