当前位置: 首页 > 知识库问答 >
问题:

DataSnapShot对象的值在getvalue(boolean.class)上返回null

柳景胜
2023-03-14

我不明白出了什么问题,编码这个的人让它完美地工作。

异常发生在以下行:if(datasnapshot.getvalue(boolean.class)){

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

//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;
}}

主体活动

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

共有1个答案

汝楷
2023-03-14

setupsystem()方法中,将监听器附加到onlineref(info/connected节点),然后将返回的值封送到boolean值。

但是,如果数据库中的指定位置没有数据,datasnapshot#getvalue()将返回null。如果发生这种情况,datasnapshot.getValue(Boolean.class)调用将创建一个Boolean变量,该变量的值为null,因此在当前If语句中不能检查该变量是否为true(请参见检查null Boolean是否为true将导致异常)。

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

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

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

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

但是,如果您试图检测连接状态,您是否打算将侦听器附加到.info/connected节点?根据文档:

对于许多与状态相关的功能,了解应用程序何时在线或离线是很有用的。Firebase Realtime Database在/.info/connected提供了一个特殊位置,该位置在Firebase Realtime Database客户端的连接状态每次更改时都会更新。下面是一个例子:

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");
  }
});
 类似资料:
  • 问题内容: 我对Java没有太多的经验。我不确定这个问题是否很愚蠢,但是我需要从Firebase实时数据库中获取一个用户名,并通过此方法返回该名称。因此,我想出了如何获得该值,但是我不明白如何通过此方法返回它。最好的方法是什么? 问题答案: 这是异步Web API的经典问题。您现在无法返回尚未加载的内容。换句话说,您不能简单地创建一个全局变量并在onDataChange()方法外部使用它,因为它将

  • 在viewmodel类中获取数据方法

  • 我试图返回这个JSON对象中第一个条目的“publisher”和“title”值。 当我运行这段代码时,我可以在开始时返回减去计数部分的对象。 然而,当我试图运行: 我得到一个错误: 我应该在代码中执行哪些操作来打印信息:

  • 我想将所有Firebase子级转换为android中的列表。 像这样的东西:

  • 从数据库中提取博客。 为什么这里的blogContent在函数的上下文中是全局的,而我们正在内部更改它,所以它应该返回值,有人能解释为什么会这样吗? 有没有不使用promise/async/await的方法>>>有人给了我答案 我如何从异步调用返回响应? 但这一点我不知道,最主要的是我不知道Ajax。

  • 我是Firebase数据库的新手,我正在遵循谷歌的文档从我的数据库中检索数据。 我有这样的结构: 我的应用程序崩溃。 我不明白与谷歌文档的区别。有人能帮帮我吗?我太纠结了! 错误是:

  • 假设每种颜色总是有一辆车。所以我总是在找一辆车,不多也不少。 如何确保始终有一个对象被找到并返回?