本文介绍了Firebase 检索数据 Null 外部方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将下面的方法放在 onCreate() 中,当应用程序启动时它会触发这个方法.但是当我尝试在 ValueEventListener() 之外获取 mName 时,它返回 null 并且应用程序崩溃了.

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**

推荐答案

正如其他人所说:Firebase 数据库中的所有数据都是异步读取的.通过在代码中添加更多日志语句,最容易看到这一点:

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:

附加监听器之前

附加监听器后

内部监听器的 onDataChange

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());
    }
});

所以所有需要数据的代码都需要在onDataChange()中.或者,您可以创建自己的自定义回调方法并从 onDataChange() 调用该方法.但逻辑总是一样的:需要脚趾数据的代码,从onDataChange() 当数据可用时触发.

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.

这篇关于Firebase 检索数据 Null 外部方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-06 08:10