mezohn adhikari
mezohn adhikari

Reputation: 87

java.lang.NullPointerException: Can't pass null for argument 'pathString' in child()

Structure of database

enter image description here

At first , while testing when the user is logged in or fully registered there is no exception or error but when the user signs out and reopen the app the app crashes . the logcat is basically pointing the error on this :

 UsersRef.child(currentUserID).addValueEventListener(new ValueEventListener()

But if i change the currentUserID to Users .. the app stops crashing and runs smoothly but it doesnot loads up the username and the profile image that is located in the naviagation drawer.

mainactivity.java

public class MainActivity extends AppCompatActivity {
    private NavigationView navigationView;
    private DrawerLayout drawerLayout;
    private RecyclerView postlist;
    private Toolbar mToolbar;
    private ActionBarDrawerToggle actionBarDrawerToggle;
    private FirebaseAuth mAuth;
    private FirebaseUser FirebaseUser;
    private DatabaseReference  UsersRef;
    private CircleImageView NavProfileImage;
    private ImageButton AddNewPostButton;
    private TextView NavProfileUserName;
    String currentUserID;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mAuth = FirebaseAuth.getInstance();
        final FirebaseUser mFirebaseUser = mAuth.getCurrentUser();
        if (mFirebaseUser != null) {
            currentUserID = mFirebaseUser.getUid();
        }




        mToolbar =(Toolbar) findViewById(R.id.main_page_toolbar);
        setSupportActionBar(mToolbar);
        getSupportActionBar().setTitle("Home");

        drawerLayout = (DrawerLayout) findViewById(R.id.drawable_layout);
       actionBarDrawerToggle =  new ActionBarDrawerToggle(MainActivity.this,drawerLayout,R.string.drawer_open, R.string.drawer_close);
        navigationView = (NavigationView)findViewById(R.id.navigation_view);
       AddNewPostButton = (ImageButton)findViewById(R.id.add_new_post_button);

        drawerLayout.addDrawerListener(actionBarDrawerToggle);
       actionBarDrawerToggle.syncState();
       getSupportActionBar().setDisplayHomeAsUpEnabled(true);


        View navView = navigationView.inflateHeaderView(R.layout.nav_header);
        NavProfileImage = (CircleImageView)navView.findViewById(R.id.nav_profile_image);
        NavProfileUserName = (TextView) navView.findViewById(R.id.nav_user_full_name);

        UsersRef = FirebaseDatabase.getInstance().getReference().child("Users");
        UsersRef.child(currentUserID).addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot)
            {
                if(dataSnapshot.exists())
                {   if (dataSnapshot.hasChild("fullname")){
                    String fullname = dataSnapshot.child("fullname").getValue().toString();
                    NavProfileUserName.setText(fullname);
                }if (dataSnapshot.hasChild("profileimage")) {
                    String image = dataSnapshot.child("profileimage").getValue().toString();
                    Picasso.with(MainActivity.this).load(image).placeholder(R.drawable.profile).into(NavProfileImage);

                }else {
                    Toast.makeText(MainActivity.this, "Profile name do not exists...", Toast.LENGTH_SHORT).show();
                }




                }
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });

        navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item)
            { UserMenuSelector(item);

                return false;
            }
        });
        AddNewPostButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SendUserToPostActivity();

            }
        });
    }

    private void SendUserToPostActivity() {
        Intent addNewPostIntent = new Intent (MainActivity.this,PostActivity.class);
        startActivity(addNewPostIntent);
    }

    @Override
    protected void onStart() {
        super.onStart();
        FirebaseUser currentUser = mAuth.getCurrentUser();
        if (currentUser == null)
        {
            sendUserToLoginActivity();
        }else{
            CheckUserExistance();
        }
    }

    private void CheckUserExistance()
    {
        final String current_user_id = mAuth.getCurrentUser().getUid();
          UsersRef.addValueEventListener(new ValueEventListener() {
              @Override
              public void onDataChange(DataSnapshot dataSnapshot) {
                  if (!dataSnapshot.hasChild(current_user_id)){
                      sendUserToSetupActivity();
                  }
              }

              @Override
              public void onCancelled(DatabaseError databaseError) {

              }
          });
    }

    private void sendUserToSetupActivity() {
        Intent setupIntent = new Intent(MainActivity.this, SetupActivity.class);
        setupIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        startActivity(setupIntent);
        finish();

    }

    private void sendUserToLoginActivity()
    {
        Intent loginIntent = new Intent(MainActivity.this, LoginActivity.class);
         loginIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
         startActivity(loginIntent);
         finish();

    }

Upvotes: 1

Views: 6195

Answers (4)

Alex Mamo
Alex Mamo

Reputation: 138869

You are getting java.lang.NullPointerException: Can't pass null for argument 'pathString' in child() because when you are signing out the user, you aren't sending him to a login activity and that's why this error. The simplest way to solve this is to use a listener. Let's assume you have two activities, the LoginActivity and the MainActivity. The listener that can be created in the LoginActivity should look like this:

FirebaseAuth.AuthStateListener authStateListener = new FirebaseAuth.AuthStateListener() {
    @Override
    public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
        FirebaseUser firebaseUser = firebaseAuth.getCurrentUser();
        if (firebaseUser != null) {
            Intent intent = new Intent(LoginActivity.this, MainActivity.class);
            startActivity(intent);
            finish();
        }
    }
};

This basically means that if the user is logged in, skip the LoginActivity and go to the MainActivity.

Instantiate the FirebaseAuth object:

FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();

And start listening for changes in your onStart() method like this:

@Override
protected void onStart() {
    super.onStart();
    firebaseAuth.addAuthStateListener(authStateListener);
}

In the MainActivity, you should do the same thing:

FirebaseAuth.AuthStateListener authStateListener = new FirebaseAuth.AuthStateListener() {
    @Override
    public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
        FirebaseUser firebaseUser = firebaseAuth.getCurrentUser();
        if (firebaseUser == null) {
            Intent intent = new Intent(MainActivity.this, LoginActivity.class);
            startActivity(intent);
        }
    }
};

Which basically means that if the user is not logged in, skip the MainActivity and go to the LoginActivity. In this activity you should do the same thing as in the LoginActivity, you should start listening for changes in the onStart().

In this way, you'll never get an error like that again.

Upvotes: 0

Muhammad Hassaan
Muhammad Hassaan

Reputation: 1017

I think you are getting null in currentUserId and then passing null to firebase. may be you are not getting user id make sure that user is logged in and then check that you are getting user id from firebase or not . if you are getting user id from firebase then try this .

UsersRef.child("Users").child(currentUserID).addValueEventListener(new 
       ValueEventListener(){ }

and make sure that all keys in your User Model class is public , i worked on firebase for about a month regularly and i faced many issues like this .

Upvotes: 2

Omkar
Omkar

Reputation: 3100

after signout mFirebaseUser gets null value so this currentUserID value also gets null to avoid nullpointerexception do null check before you use currentUserID like below code

public class MainActivity extends AppCompatActivity {
private NavigationView navigationView;
private DrawerLayout drawerLayout;
private RecyclerView postlist;
private Toolbar mToolbar;
private ActionBarDrawerToggle actionBarDrawerToggle;
private FirebaseAuth mAuth;
private FirebaseUser FirebaseUser;
private DatabaseReference  UsersRef;
private CircleImageView NavProfileImage;
private ImageButton AddNewPostButton;
private TextView NavProfileUserName;
String currentUserID;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    mAuth = FirebaseAuth.getInstance();
    final FirebaseUser mFirebaseUser = mAuth.getCurrentUser();
    if (mFirebaseUser != null) {
        currentUserID = mFirebaseUser.getUid();
    }




    mToolbar =(Toolbar) findViewById(R.id.main_page_toolbar);
    setSupportActionBar(mToolbar);
    getSupportActionBar().setTitle("Home");

    drawerLayout = (DrawerLayout) findViewById(R.id.drawable_layout);
   actionBarDrawerToggle =  new ActionBarDrawerToggle(MainActivity.this,drawerLayout,R.string.drawer_open, R.string.drawer_close);
    navigationView = (NavigationView)findViewById(R.id.navigation_view);
   AddNewPostButton = (ImageButton)findViewById(R.id.add_new_post_button);

    drawerLayout.addDrawerListener(actionBarDrawerToggle);
   actionBarDrawerToggle.syncState();
   getSupportActionBar().setDisplayHomeAsUpEnabled(true);


    View navView = navigationView.inflateHeaderView(R.layout.nav_header);
    NavProfileImage = (CircleImageView)navView.findViewById(R.id.nav_profile_image);
    NavProfileUserName = (TextView) navView.findViewById(R.id.nav_user_full_name);

    UsersRef = FirebaseDatabase.getInstance().getReference().child("Users");
      // replace below code
     if (mFirebaseUser != null) {

    UsersRef.child(currentUserID).addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot)
        {
            if(dataSnapshot.exists())
            {   if (dataSnapshot.hasChild("fullname")){
                String fullname = dataSnapshot.child("fullname").getValue().toString();
                NavProfileUserName.setText(fullname);
            }if (dataSnapshot.hasChild("profileimage")) {
                String image = dataSnapshot.child("profileimage").getValue().toString();
                Picasso.with(MainActivity.this).load(image).placeholder(R.drawable.profile).into(NavProfileImage);

            }else {
                Toast.makeText(MainActivity.this, "Profile name do not exists...", Toast.LENGTH_SHORT).show();
            }




            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });

    }else{
     sendUserToLoginActivity();
    }

    navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item)
        { UserMenuSelector(item);

            return false;
        }
    });
    AddNewPostButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            SendUserToPostActivity();

        }
    });
}

private void SendUserToPostActivity() {
    Intent addNewPostIntent = new Intent (MainActivity.this,PostActivity.class);
    startActivity(addNewPostIntent);
}

@Override
protected void onStart() {
    super.onStart();
    FirebaseUser currentUser = mAuth.getCurrentUser();
    if (currentUser == null)
    {
        sendUserToLoginActivity();
    }else{
        CheckUserExistance();
    }
}

private void CheckUserExistance()
{
    final String current_user_id = mAuth.getCurrentUser().getUid();
      UsersRef.addValueEventListener(new ValueEventListener() {
          @Override
          public void onDataChange(DataSnapshot dataSnapshot) {
              if (!dataSnapshot.hasChild(current_user_id)){
                  sendUserToSetupActivity();
              }
          }

          @Override
          public void onCancelled(DatabaseError databaseError) {

          }
      });
}

private void sendUserToSetupActivity() {
    Intent setupIntent = new Intent(MainActivity.this, SetupActivity.class);
    setupIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
    startActivity(setupIntent);
    finish();

}

private void sendUserToLoginActivity()
{
    Intent loginIntent = new Intent(MainActivity.this, LoginActivity.class);
     loginIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
     startActivity(loginIntent);
     finish();

}

OR you can check directly here also

 if (mFirebaseUser != null) {
        currentUserID = mFirebaseUser.getUid();
    }else{
        sendUserToLoginActivity();
    }

Upvotes: 2

mark922
mark922

Reputation: 1167

If you check I believe you don't have any logged in user that's why you are getting null value in currentUserID.

You are checking if user is logged in or not in OnStart(), you have to check that in onCreate() also. Because in activity lifecycle onCreate() is called before onStart().

Here is how your onCreate function should look:

@Override
protected void onCreate(Bundle savedInstanceState) {
    FirebaseUser currentUser = mAuth.getCurrentUser();
    if (currentUser == null)
    {
        sendUserToLoginActivity();
    }else{
        CheckUserExistance();
    }
    //Your code ...
}

Upvotes: 1

Related Questions