Firebase retrieve data Null outside method

大城市里の小女人 提交于 2019-12-29 02:12:33

问题


I put the below method inside an onCreate(), when the app launch it will trigger this method. But when I try to to get mName outside the ValueEventListener(), it return null and the app crashed.

Anyone know why this issue happen?

 ValueEventListener postListener = new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            UserDetails info = dataSnapshot.getValue(UserDetails.class);
            Log.d(TAG, String.valueOf(dataSnapshot));

            mName = info.getName();
            **Log.d(TAG, mName); // HERE GET THE NAME**

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            Log.w(TAG, "getUser:onCancelled", databaseError.toException());
        }
    };
    mDatabase.child("Admin")
            .child("Info")
            .child(uid)
            .addValueEventListener(postListener);

    **Log.d(TAG, mName); // HERE GET NULL**

回答1:


As the others have said: all data from the Firebase Database is read asynchronously. It's easiest to see this by adding some more log statements to your code:

Log.d(TAG, "Before attaching listener");
mDatabase.child("Admin")
        .child("Info")
        .child(uid)
        .addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        Log.d(TAG, "In listener's onDataChange");
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {
        Log.w(TAG, "getUser:onCancelled", databaseError.toException());
    }
});
Log.d(TAG, "After attaching listener");

Unlike what you may expect, the output of this is:

Before attaching listener

After attaching listener

Inside listener's onDataChange

The way to deal with the asynchronous behavior is to reframe your problem.

Right now your code is written: first we load the data, then we log it.

If you reframe the problem to: "whenever the data is loaded, we log it", you get code like this:

mDatabase.child("Admin")
        .child("Info")
        .child(uid)
        .addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        UserDetails info = dataSnapshot.getValue(UserDetails.class);
        Log.d(TAG, String.valueOf(dataSnapshot));

        mName = info.getName();
        Log.d(TAG, mName);

    }

    @Override
    public void onCancelled(DatabaseError databaseError) {
        Log.w(TAG, "getUser:onCancelled", databaseError.toException());
    }
});

So all code that needs the data, needs to be inside the onDataChange(). Alternatively, you can make your own custom callback method and invoke that from onDataChange(). But the logic is always the same: the code that needs toe data, is triggered from onDataChange() when the data is available.




回答2:


That's because Firebase still didn't retrieve the data yet at the time you do:

Log.d(TAG, mName);

mName is currently null since this line was executed before Firebase got the data.

To solve this, you have to Log.d(TAG, mName) inside the onDataChange method. Otherwise, it will be null as you haven't set the value yet (since Firebase still didn't get the value yet).



来源:https://stackoverflow.com/questions/40447073/firebase-retrieve-data-null-outside-method

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!