Liam G
Liam G

Reputation: 791

Firebase onDataChange - Value Event Listener not listening for changes

I am trying to read a list of data from a user account which looks like this: db

But the onDataChange listener is not being called.

I would like to get the values of "checked" and "desc"; However, when I add a listenForSingleValueEvent listener like below, onDataChange is not called and I do not retrieve the values.

DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("accounts")
            .child(uid).child("user_t").child(item_id);
//"user_t" has been shortened for this post

    databaseReference.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            Log.i(TAG, "onDataChange: Getting single data");

            String name = (String) dataSnapshot.child("checked").getValue();
            String date = (String) dataSnapshot.child("desc").getValue();
        }
    //on Cancel etc..
    };

Even with only:

String name = (String) dataSnapshot.child("checked").getValue();"

Inside onDataChange it still will not fire. From what I've read from the Firebase docs, I must use a listener to read data.

I have similar code in another section of the app which more or less does the same thing as the above code is supposed to and it works perfectly.

I've been having a lot of trouble with Firebase recently so any help appreciated. Cheers!

EDIT: Some more code with the same result:

DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("accounts").child(uid);
databaseReference.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        Log.i(TAG, "onDataChange: ");
        String name = dataSnapshot.child("name").getValue().toString();
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {

    }
});

EDIT 2: I am able to create a key and set a value to it, in the account section and the item section, but it will call the onDataChange function. I have been able to bypass this issue; however, the listener is then called once its calling class has been deconstructed and a NullPointerException is thrown because the class level variables no longer exist.

EDIT 3 - Entire class:

This is a different class but I am having the exact same problem with it.

public class StartActivity extends AppCompatActivity {

//firebase variables
private FirebaseAuth mAuth;
private FirebaseUser currentUser;
private FirebaseDatabase database;
private DatabaseReference userReference;
private String uid;
private String accountType;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    //set splash theme
    setTheme(R.style.SplashStyle);
    super.onCreate(savedInstanceState);

    //get an authentication instance
    mAuth = FirebaseAuth.getInstance();
    //get user database
    database = FirebaseDatabase.getInstance();
    userReference = database.getReference(ACCOUNTS);


    //get the user and check if logged in
    currentUser = mAuth.getCurrentUser();
    if (currentUser != null){
        uid = currentUser.getUid();
        getAccountType();

        //open the dashboard
        openDashboard();
    }else{
        openLogin();
    }

    finish();
}

private void openDashboard() {
    Intent dashboard = new Intent(this,Dashboard.class);

    dashboard.putExtra(String_Values.ACCOUNT_TYPE,accountType);
    dashboard.putExtra(String_Values.ACCOUNT_UID,uid);

    startActivity(dashboard);
    finish();

}

private void openLogin(){
    Intent loginIntent = new Intent(this,Login.class);
    startActivity(loginIntent);
}


private void getAccountType(){
    FirebaseDatabase database = FirebaseDatabase.getInstance();
    DatabaseReference databaseReference = database.getReference(ACCOUNTS).child(uid);
    Log.i(String_Values.TAG, "uid: " + uid);
    databaseReference.addListenerForSingleValueEvent(get_account_listener);
}

ValueEventListener get_account_listener = new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        accountType = dataSnapshot.child(TYPE).getValue().toString();
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {
        Log.i(String_Values.TAG, "onCancelled: " + databaseError.getMessage());
    }
};

}

Upvotes: 0

Views: 4650

Answers (2)

Liam G
Liam G

Reputation: 791

Thanks to Alex Mamo for his answer here. Perfectly explained.

Upvotes: 0

Alex Mamo
Alex Mamo

Reputation: 138824

You cannot get anything because you aren't looping to get the children within the DataSnapshot object. So to solve this, please use the following lines of code:

DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("accounts")
        .child(uid).child("user_t");
databaseReference.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        for(DataSnapshot ds : dataSnapshot.getChildren()) {
            String name = ds.child("checked").getValue(String.class);
            String date = ds.child("desc").getValue(String.class);
        }

    }

    @Override
    public void onCancelled(@NonNull DatabaseError databaseError) {
        Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
    }
};

If you it still doesn't fire, please check the logcat to see that databaseError.getMessage() returns.

Upvotes: 2

Related Questions