从Firebase数据库有效获取用户数据

时间:2018-10-18 00:53:32

标签: java android firebase firebase-realtime-database

我正在尝试访问要在屏幕上显示的用户名,并且正在从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并崩溃。

有帮助吗?

2 个答案:

答案 0 :(得分:0)

从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

为了表明您并不孤单,这是有关该主题的先前问题:

答案 1 :(得分:-1)

这可能是由于各种原因而发生的,原因之一可能是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");