DataSnapShot 对象的值在 getvalue(Boolean.class) 上返回 null
DataSnapShot Object's value returning null on getvalue(Boolean.class)
我正在做一个在线教程的实时跟踪应用程序,这里我正在使用 firebase 设置在线状态系统。但它崩溃了:
/java.lang.NullPointerException: 尝试在空对象引用上调用虚拟方法 'boolean java.lang.Boolean.booleanValue()'
我不明白编写此代码的人有什么问题使它工作得很好。
The exception is happening at this line :if(dataSnapshot.getValue(Boolean.class)){
当我在屏幕上记录这个时,datasnapshot 对象有一个键但没有值
求助!
在线列表Class
//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);
}
}
用户Class
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();
}
}}
它是空的,因为它不存在于数据库中..
onlineRef = FirebaseDatabase.getInstance().getReference().child("info/connected");
您正在查询上述位置。所以 dataSnapshot
是上面的快照..
if(dataSnapshot.getValue(Boolean.class)){
这在数据库中不存在..因此你得到那个错误
您似乎在数据库中没有值。这将处理错误
if(dataSnapshot.getValue(Boolean.class) != null && dataSnapshot.getValue(Boolean.class)){
在您的 setupSystem()
方法中,您将监听器附加到 onlineRef
(info/connected
节点),然后将 returned 值编组到 Boolean
值。
然而,DataSnapshot#getValue()
will return null
if there is no data at the specified location in the database. If this happens, the dataSnapshot.getValue(Boolean.class)
call will create a Boolean
variable with the value of null
, which then cannot be checked for a true value in your current if statement (see Check if null Boolean is true results in exception).
您可以首先通过向 if 语句添加空检查来检查 getValue()
是否 return null
:
if(dataSnapshot.getValue() != null && dataSnapshot.getValue(Boolean.class)){
// ...
}
或者使用 DataSnapshot#exists()
:
检查位置是否存在
if(dataSnapshot.exists() && dataSnapshot.getValue(Boolean.class)){
// ...
}
但是,如果您尝试 detect connection state,您的意思是将侦听器附加到 .info/connected
节点吗?来自文档:
For many presence-related features, it is useful for your app to know
when it is online or offline. Firebase Realtime Database provides a
special location at /.info/connected
which is updated every time the
Firebase Realtime Database client's connection state changes. Here is
an example:
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");
}
});
我正在做一个在线教程的实时跟踪应用程序,这里我正在使用 firebase 设置在线状态系统。但它崩溃了:
/java.lang.NullPointerException: 尝试在空对象引用上调用虚拟方法 'boolean java.lang.Boolean.booleanValue()'
我不明白编写此代码的人有什么问题使它工作得很好。
The exception is happening at this line :if(dataSnapshot.getValue(Boolean.class)){
当我在屏幕上记录这个时,datasnapshot 对象有一个键但没有值
求助!
在线列表Class
//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);
}
}
用户Class
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();
}
}}
它是空的,因为它不存在于数据库中..
onlineRef = FirebaseDatabase.getInstance().getReference().child("info/connected");
您正在查询上述位置。所以 dataSnapshot
是上面的快照..
if(dataSnapshot.getValue(Boolean.class)){
这在数据库中不存在..因此你得到那个错误
您似乎在数据库中没有值。这将处理错误
if(dataSnapshot.getValue(Boolean.class) != null && dataSnapshot.getValue(Boolean.class)){
在您的 setupSystem()
方法中,您将监听器附加到 onlineRef
(info/connected
节点),然后将 returned 值编组到 Boolean
值。
然而,DataSnapshot#getValue()
will return null
if there is no data at the specified location in the database. If this happens, the dataSnapshot.getValue(Boolean.class)
call will create a Boolean
variable with the value of null
, which then cannot be checked for a true value in your current if statement (see Check if null Boolean is true results in exception).
您可以首先通过向 if 语句添加空检查来检查 getValue()
是否 return null
:
if(dataSnapshot.getValue() != null && dataSnapshot.getValue(Boolean.class)){
// ...
}
或者使用 DataSnapshot#exists()
:
if(dataSnapshot.exists() && dataSnapshot.getValue(Boolean.class)){
// ...
}
但是,如果您尝试 detect connection state,您的意思是将侦听器附加到 .info/connected
节点吗?来自文档:
For many presence-related features, it is useful for your app to know when it is online or offline. Firebase Realtime Database provides a special location at
/.info/connected
which is updated every time the Firebase Realtime Database client's connection state changes. Here is an example: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"); } });