Firebase Datasnapshot returns null value

Tags: , , ,



I want to retrieve this value from this node (“id”), and the value i get is null. I have googled so many solutions that this might have to do with asynchronous way or something, i guess?

This is the database, and the highlighted node is the value i would like to get:

This is the database, and the highlighted node is the value i would like to get

This is my code:

            reference = FirebaseDatabase.getInstance().getReference();
            id = null;
            Query lastQuery = reference.child("Donation Request").orderByKey().limitToLast(1);
            lastQuery.addListenerForSingleValueEvent(new ValueEventListener()
            {
                @Override
                public void onDataChange(@NonNull DataSnapshot dataSnapshot)
                {
                    if (dataSnapshot.child("id").exists())
                    {
                        id = dataSnapshot.child("id").getValue().toString();
                        int index = Integer.parseInt(id) + 1;
                        id = Integer.toString(index);
                        Toast.makeText(getApplicationContext(), "It works!!!", Toast.LENGTH_SHORT).show();
                    }
                    else
                    {
                        id = "1";
                        Toast.makeText(getApplicationContext(), "It doesn't work.", Toast.LENGTH_SHORT).show();
                    }
                }
                @Override
                public void onCancelled(@NonNull DatabaseError databaseError)
                {

                }
            });

Most appreciated if someone can help me out of this!

Answer

When you execute a query against the Firebase Database, there will potentially be multiple results. So the snapshot contains a list of those results. Even if there is only a single result, the snapshot will contain a list of one result.

Your onDataChange needs to handle this list by looping over dataSnapshot.getChildren()):

reference = FirebaseDatabase.getInstance().getReference();
id = null;
Query lastQuery = reference.child("Donation Request").orderByKey().limitToLast(1);
lastQuery.addListenerForSingleValueEvent(new ValueEventListener()
{
    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot)
    {
        for (DataSnapshot snapshot: dataSnapshot.getChildren()) {
            if (snapshot.hasChild("id"))
            {
                id = snapshot.child("id").getValue(String.class);
                int index = Integer.parseInt(id) + 1;
                id = Integer.toString(index);
                Toast.makeText(getApplicationContext(), "It works!!!", Toast.LENGTH_SHORT).show();
            }
            else
            {
                id = "1";
                Toast.makeText(getApplicationContext(), "It doesn't work.", Toast.LENGTH_SHORT).show();
            }
        }
    }
    @Override
    public void onCancelled(@NonNull DatabaseError databaseError)
    {
        throw databaseError.toException(); // never ignore errors.
    }
});

A few more notes:

  • Any use of id needs to happen inside onDataChange, or be called from there. Outside of that, you won’t have any guarantees that id will have been assigned the value you expect.
  • Using toasts for debugging is bound to become confusing. I highly recommend using Log.d(...) and friends, and studying the output (and its order) in the logcat output of your app.


Source: stackoverflow