【问题标题】:Efficiently getting user data from Firebase Database高效地从 Firebase 数据库获取用户数据
【发布时间】:2018-10-18 00:53:32
【问题描述】:

我正在尝试访问要在屏幕上显示的用户名,并且我正在从我的 Firebase 数据库中检索用户名。

获取用户名的代码有点长,

myRef.addListenerForSingleValueEvent(new ValueEventListener() {

        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            String userName = dataSnapshot.child("userName").getValue(String.class);
            navUsername.setText(userName);
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            throw databaseError.toException();
        }
    });

所以我试图让那段代码返回一个名为“specUserName”的字符串,这样我就可以轻松地从任何类访问它,而不必每次都输入那个冗长的代码字符串。在我的 User.class 中,我添加了这个

    public String getUserName() {
    myRef.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            specUserName = dataSnapshot.child("userName").getValue(String.class);
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            throw databaseError.toException();
        }
    });
    return specUserName;
}

我正试图通过这样做在我的 HomePage.class 中检索它

    users.getUserName();
    navUsername.setText(users.specUserName);

但是现在主页总是在我打开它时崩溃,这是我在 Logcat 中收到的错误。

java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.example.brent.fifty_fifty.User.getUserName()' on a null object reference
    at com.example.brent.fifty_fifty.HomePage.onCreateOptionsMenu(HomePage.java:84)

HomePage:84 是我调用 getUserName() 方法的地方,但它一直返回 null 并崩溃。

有什么帮助吗?

【问题讨论】:

    标签: java android firebase firebase-realtime-database


    【解决方案1】:

    数据是从 Firebase 异步加载的。由于您不能让getUserName 等到数据可用(这意味着您的应用程序变得无响应),因此您无法像这样返回用户名。

    要了解原因,请像这样放置一些日志记录语句:

    System.out.println("Before attaching listener");
    myRef.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            System.out.println("Got data");
        }
    
        @Override
        public void onCancelled(DatabaseError databaseError) {
            throw databaseError.toException();
        }
    });
    System.out.println("After attaching listener");
    

    当您运行此代码时,它会打印:

    附加监听器之前

    附加监听器后

    得到数据

    这可能不是您所期望的。但这绝对解释了为什么您不能返回用户名。到return 语句执行时,数据还没有加载,onDataChange() 还没有被调用。

    有两种常见的解决方法:

    1. 将需要用户名的代码移入getUserName方法。这是迄今为止最简单的方法,但会降低您的 getUserName 方法的可重用性。
    2. 创建一个回调接口,将其传递给getUserName,然后在加载用户名时调用该接口。这类似于 ValueEventListener.onDataChange 用于 Firebase 本身,但特定于您的应用逻辑。

    我建议您不要在此处显示两者的代码,而是在此处查看我的答案:getContactsFromFirebase() method return an empty list

    为了表明您并不是唯一一个为此苦苦挣扎的人,这里有一些关于该主题的先前问题:

    【讨论】:

    • 嗨弗兰克,这真的让我非常接近解决我的问题,非常感谢。我查看了您发送的有关此问题的其他一些示例,并且已经能够解决一些问题。我已经准备好回调并设置了所有内容,但是我正在努力弄清楚要调用什么来检索“public void getUser(final MyCallback callback)”产生的字符串。我在需要它的地方正确调用该方法作为'getUser(new MyCallback ...),但我正在尝试更新UI以显示正在检索的人员用户名,我应该放入什么变量
    • 将我的 TextView 之一设置为“public void getUser”产生的字符串的地方?抱歉,如果这在 cmets 中有点令人困惑 - 如果您不明白我在问什么,我可以尝试提供更多信息
    • 嘿@Co​​derKlipto。很高兴听到你取得了进展。我不确定我是否理解新问题,但这可能是由于缺乏上下文。最好不要描述您拥有的东西,而是显示 minimal code that reproduces the problem。在这一点上,发布一个新问题可能会更好,因为 cmets 中的代码很难在单个语句之外阅读。
    【解决方案2】:

    这可能由于各种原因而发生,其中之一可能是 myRef 在您的 User 类中未正确引用您的数据库或任何其他原因。

    但是,您必须获得用户名的问题可以通过多种方式解决。

    首先,如果您使用电子邮件/密码注册用户,则您已经拥有他们在其 GoogleID 中的user 的用户名。

    您可以通过以下代码轻松获取username

    FirebaseAuth mAuth = FirebaseAuth.getInstance();
    String username = mAuth.getCurrentUser.getUsername();
    

    如果您在一个活动中拥有数据,也很容易将数据传递给下一个活动。您可以使用putExtra() 方法来做到这一点。

    // to send data to MainActivity from the class where you first got username value
    
    Intent intent = new Intent(getBaseContext(), MainActivity.class);
    intent.putExtra("username", userName);
    startActivity(intent);
    
    // to recieve data in MainActivity
    
    String uname = getIntent().getStringExtra("username");
    

    【讨论】:

      猜你喜欢
      • 2021-02-09
      • 2020-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-22
      • 2023-03-31
      相关资源
      最近更新 更多