【问题标题】:DataSnapShot Object's value returning null on getvalue(Boolean.class)DataSnapShot 对象的值在 getvalue(Boolean.class) 上返回 null
【发布时间】:2017-10-29 08:53:50
【问题描述】:

我正在根据在线教程做一个实时跟踪应用程序,这里我正在使用 firebase 设置存在系统。但它崩溃了:

/java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法“boolean java.lang.Boolean.booleanValue()”

我不明白编写此代码的人有什么问题,它工作得很好。

异常发生在这一行:if(dataSnapshot.getValue(Boolean.class)){

当我在屏幕上登录时,datasnapshot 对象有一个键但没有值

帮助!

ListOnline 类

//firebase
DatabaseReference onlineRef,currentUserRef,counterRef;
FirebaseRecyclerAdapter<User,ListOnlineViewHolder> adapter;

//View
RecyclerView listOnline;
RecyclerView.LayoutManager layoutManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_list_online);

    //setting the recyclerview
    listOnline = (RecyclerView)findViewById(R.id.listOnlineRecyclerview);
    listOnline.setHasFixedSize(true);
    layoutManager = new LinearLayoutManager(this);
    listOnline.setLayoutManager(layoutManager);

    //set toolbar and menu / join,logout
    Toolbar toolbar = (Toolbar)findViewById(R.id.toolbarID);
    toolbar.setTitle("Presence System");
    setSupportActionBar(toolbar);

    //firebase
    onlineRef = FirebaseDatabase.getInstance().getReference().child("info/connected");
    counterRef = FirebaseDatabase.getInstance().getReference("lastOnline"); //create new child name lastOnline
    currentUserRef = FirebaseDatabase.getInstance().getReference().child(FirebaseAuth.getInstance().getCurrentUser().getUid());

    setupSystem();
    //after setup we load all users and display in recyclerview
    //this is online list
    updateList();
}

private void updateList() {
    adapter = new FirebaseRecyclerAdapter<User, ListOnlineViewHolder>(
            User.class,R.layout.user_layout,ListOnlineViewHolder.class,counterRef
    ) {
        @Override
        protected void populateViewHolder(ListOnlineViewHolder viewHolder, User model, int position) {
            viewHolder.emailTextView.setText(model.getEmail());
        }

    };
    adapter.notifyDataSetChanged();
    listOnline.setAdapter(adapter);
}

private void setupSystem() {
    onlineRef.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
                if(dataSnapshot.getValue(Boolean.class)){
                    currentUserRef.onDisconnect().removeValue();
                    //set online user in list
                    counterRef.child(FirebaseAuth.getInstance().getCurrentUser().getUid())
                            .setValue(FirebaseAuth.getInstance().getCurrentUser().getEmail(),"Online");
                    adapter.notifyDataSetChanged();
                }
            }



        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });
    counterRef.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            for(DataSnapshot postSnapshot:dataSnapshot.getChildren()){
                User user = postSnapshot.getValue(User.class);
                Log.d("LOG",""+user.getEmail()+"is "+user.getStatus());
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater menuInflater = getMenuInflater();
    menuInflater.inflate(R.menu.main_menu,menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()){
        case R.id.action_join:
            counterRef.child(FirebaseAuth.getInstance().getCurrentUser().getUid())
                    .setValue(FirebaseAuth.getInstance().getCurrentUser().getEmail(),"Online");
            break;
        case R.id.action_logout:
            currentUserRef.removeValue();

    }
    return super.onOptionsItemSelected(item);
}

}

用户类

public class User {
private String email,status;


public User(String email, String status) {
    this.email = email;
    this.status = status;
}

public User() {

}

public String getEmail() {
    return email;
}

public void setEmail(String email) {
    this.email = email;
}

public String getStatus() {
    return status;
}

public void setStatus(String status) {
    this.status = status;
}}

MainActivity

public class MainActivity extends AppCompatActivity {

Button signInButton;
private final static int LOGIN_PERMISSION = 1000;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    signInButton = (Button) findViewById(R.id.signInButton);
    signInButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            startActivityForResult(AuthUI.getInstance().createSignInIntentBuilder().setAllowNewEmailAccounts(true).build(),LOGIN_PERMISSION);

        }

    });
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {

    if(requestCode == LOGIN_PERMISSION){
        startNewActivity(resultCode,data);
    }
}

private void startNewActivity(int resultcode, Intent data) {

    if(resultcode == RESULT_OK){
        Intent intent = new Intent(MainActivity.this,ListOnline.class);
        startActivity(intent);
        finish();

    }
    else{
        Toast.makeText(this,"login failed!!",Toast.LENGTH_SHORT).show();
    }
}}

【问题讨论】:

标签: android database firebase firebase-realtime-database tracking


【解决方案1】:

在您的 setupSystem() 方法中,您将侦听器附加到 onlineRef(info/connected 节点),然后将返回的值编组为 Boolean 值。

但是,如果数据库中的指定位置没有数据,DataSnapshot#getValue() 将返回 null。如果发生这种情况,dataSnapshot.getValue(Boolean.class) 调用将创建一个值为null 的Boolean 变量,然后无法在当前的 if 语句中检查其是否为真值(请参阅Check if null Boolean is true results in exception)。

您可以首先通过在 if 语句中添加空检查来检查 getValue() 是否返回 null:

if(dataSnapshot.getValue() != null && dataSnapshot.getValue(Boolean.class)){
    // ...
}

或者使用DataSnapshot#exists()检查该位置是否存在:

if(dataSnapshot.exists() && dataSnapshot.getValue(Boolean.class)){
    // ...
}

但是,如果您尝试detect connection state,您的意思是要将侦听器附加到.info/connected 节点吗?根据文档:

对于许多与状态相关的功能,了解您的应用很有用 当它在线或离线时。 Firebase 实时数据库提供了一个 /.info/connected 的特殊位置,每次更新时都会更新 Firebase 实时数据库客户端的连接状态更改。这是 一个例子:

DatabaseReference connectedRef = FirebaseDatabase.getInstance().getReference(".info/connected");
connectedRef.addValueEventListener(new ValueEventListener() {
  @Override
  public void onDataChange(DataSnapshot snapshot) {
    boolean connected = snapshot.getValue(Boolean.class);
    if (connected) {
      System.out.println("connected");
    } else {
      System.out.println("not connected");
    }
  }

  @Override
  public void onCancelled(DatabaseError error) {
    System.err.println("Listener was cancelled");
  }
});

【讨论】:

  • 我修好了它是一个小“。”信息/连接行中缺少我有一个新的崩溃虽然
  • com.google.firebase.database.DatabaseException:无法转换 java.lang.String 类型的对象:用户 user = postSnapshot.getValue(User.class);
  • 这将来自您尝试编组到 User 实例的 /lastOnline 位置。你能分享你的数据库结构吗?此位置的值可能与您的 User 类不匹配。
  • 我是 firebase 的菜鸟,我该如何分享我的结构? :|
  • @Akay 最快的方法是从 Firebase 控制台截取屏幕截图并将其编辑到您的问题中。此外,由于您的问题与原始问题不同,因此可能值得在此处接受答案(在赞成按钮下方打勾)并将其作为新问题发布以吸引更多关注和答案。
【解决方案2】:

它为空,因为它在数据库中不存在..

 onlineRef = FirebaseDatabase.getInstance().getReference().child("info/connected");

您正在查询上述位置。所以dataSnapshot是上面的快照..

if(dataSnapshot.getValue(Boolean.class)){

这在数据库中不存在.. 因此你得到那个错误

【讨论】:

  • 我该如何解决这个问题?我是 Firebase 的新手,所以不要介意我的无知
  • @Akay 你是什么意思设置两个用户,比如老师和学生?
  • 对不起,我的意思是我的数据库中有两个用户。怎么可能是空的
  • 它为空,因为 getValue(Boolean.class) 不存在
【解决方案3】:

您的数据库中似乎没有值。这将处理错误

if(dataSnapshot.getValue(Boolean.class) != null && dataSnapshot.getValue(Boolean.class)){

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-12-11
    • 1970-01-01
    • 1970-01-01
    • 2021-12-10
    • 1970-01-01
    • 2020-09-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多