DataSnapShot Object's value returning null on getvalue(Boolean.class)

岁酱吖の 提交于 2021-02-08 11:20:09

问题


I'm doing a realtime tracking application from a tutorial online, Here i'm setting the presence system using firebase. But it's crashing with:

/java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.Boolean.booleanValue()' on a null object reference

I don't understand what's wrong the guy who coded this has it working perfectly.

The exception is happening at this line :if(dataSnapshot.getValue(Boolean.class)){

When i log this on screen the datasnapshot object has a key but no value

HELP!

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

}

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

回答1:


In your setupSystem() method, you are attaching a listener to onlineRef (the info/connected node) and then marshalling the returned value to a Boolean value.

However, 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).

You could check that getValue() does not return null first by adding a null-check to your if statement:

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

Or check that the location exists using DataSnapshot#exists():

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

However, if you're trying to detect connection state, did you mean to attach the listener to the .info/connected node instead? As from the documentation:

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



回答2:


its null since it does not exist in the database..

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

you are querying on the above location. So dataSnapshot is a snapshot of the above..

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

This does not exist in the database.. Thus you get that error




回答3:


It seems that you do not have a value in database. This will handle the error

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


来源:https://stackoverflow.com/questions/46998399/datasnapshot-objects-value-returning-null-on-getvalueboolean-class

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!