0

I'm getting this error when i create new user on firebase from my sign-up form :

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

I search about this error on google and on YouTube but i don't found something for my program.

Here is a part of my code on SignUpActivity.java:

    final EditText email = findViewById(R.id.email_address);
    final EditText display_name = findViewById(R.id.display_name);
    final EditText password = findViewById(R.id.pass_sign_up);
    final EditText comfirm_pass = findViewById(R.id.comfirm_pass);
    final Button submit = findViewById(R.id.submit_btn_signup);
    final TextView signin = findViewById(R.id.textView8);
    final FirebaseAuth mAuth = FirebaseAuth.getInstance();
    final String[] error = new String[1];
    final ProgressBar loading_icon = findViewById(R.id.progressBar2);


    // hide loading icon \\
    loading_icon.setVisibility(View.GONE);

    signin.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(SignupActivity.this,MainActivity.class);
            startActivity(intent);
        }
    });

    submit.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            loading_icon.setVisibility(View.VISIBLE);

            String email_input = email.getText().toString();
            String display_name_input = display_name.getText().toString();
            String password_input = password.getText().toString();
            String comfirm_pass_input = comfirm_pass.getText().toString();

            if (email_input.isEmpty() || display_name_input.isEmpty() || password_input.isEmpty() || comfirm_pass_input.isEmpty()){
                error[0] = "Please fill all the values and try again";
                Toast.makeText(SignupActivity.this, error[0], Toast.LENGTH_LONG).show();
                loading_icon.setVisibility(View.GONE);
            }else{
                if (!password_input.equals(comfirm_pass_input)){
                    error[0] = "passwords do not match";
                    Toast.makeText(SignupActivity.this, error[0], Toast.LENGTH_LONG).show();
                    loading_icon.setVisibility(View.GONE);
                }else{
                    mAuth.createUserWithEmailAndPassword(email_input,password_input).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
                        @Override
                        public void onComplete(@NonNull @NotNull Task<AuthResult> task) {
                            if (task.isSuccessful()){
                                finish();
                                // set display name for user \\
                                FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
                                UserProfileChangeRequest profileUpdates = new UserProfileChangeRequest.Builder()
                                        .setDisplayName(display_name_input).build();
                                user.updateProfile(profileUpdates);

                                DatabaseReference mRef = FirebaseDatabase.getInstance().getReference();

                                mRef.addValueEventListener(new ValueEventListener(){
                                    @Override
                                    public void onDataChange(@NotNull DataSnapshot dataSnapshot){

                                        // Get the max_user_id to set the main user id and create the user on Firebase real-time DB \\
                                        String maxUserId = dataSnapshot.child("max_user_id").getValue().toString();
                                        int maxUserIdToInt = Integer.parseInt(maxUserId);
                                        int userId = maxUserIdToInt+1;
                                        newUserId = String.valueOf(userId);
                                        mRef.child("users").child(newUserId).child("name").setValue(display_name_input);
                                    }

                                    @Override
                                    public void onCancelled(@NotNull DatabaseError databaseError){
                                        Toast.makeText(SignupActivity.this,"error: " + databaseError, Toast.LENGTH_LONG).show();
                                    }
                                });

                                mRef.child("users").child(newUserId);
                                

                                Intent intent = new Intent(SignupActivity.this,HomeActivity.class);
                                startActivity(intent);
                            }else{
                                loading_icon.setVisibility(View.GONE);
                                error[0] = "failed to sign up, the email address aleready exist or the password lenght is lower than 6 characters";
                                Toast.makeText(SignupActivity.this, error[0], Toast.LENGTH_LONG).show();
                            }
                        }
                    });
                }
            }
        }
    });

}

}

NOTE: i'm beginner on firebase for android applications. Also i created today my account here and stackoverflow is so cool and helpfull

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807

2 Answers2

1

When you call child(), you need to pass a non-null String as the parameter. In your case, newUserId is null for some reason. Hence you call child(newUserId), Firebase throws an exception.

The way forward should be check if the way you are accessing child with path max_user_id is correct or not. You can keep a breakpoint at that location and then go through the structure of dataSnapshot to get the correct path.

Subhrajyoti Sen
  • 1,525
  • 14
  • 18
  • i have write a variable in database with this name and i try to get the value of it on int from string and maybe there is a problem with the convert from string to int. That's why is null maybe – George Sepetadelis Jan 03 '21 at 20:07
0

The problem is in the last line in this fragment:

DatabaseReference mRef = FirebaseDatabase.getInstance().getReference();

mRef.addValueEventListener(new ValueEventListener(){
    @Override
    public void onDataChange(@NotNull DataSnapshot dataSnapshot){

        // Get the max_user_id to set the main user id and create the user on Firebase real-time DB \\
        String maxUserId = dataSnapshot.child("max_user_id").getValue().toString();
        int maxUserIdToInt = Integer.parseInt(maxUserId);
        int userId = maxUserIdToInt+1;
        newUserId = String.valueOf(userId);
        mRef.child("users").child(newUserId).child("name").setValue(display_name_input);
    }

    @Override
    public void onCancelled(@NotNull DatabaseError databaseError){
        Toast.makeText(SignupActivity.this,"error: " + databaseError, Toast.LENGTH_LONG).show();
    }
});

mRef.child("users").child(newUserId);

That line does nothing meaningful, but it executes before newUserId = String.valueOf(userId), which means you're passing in an initialized newUserId and that causes the error messages.

Since this line mRef.child("users").child(newUserId); does nothing anyway, you can safely remove it.

As a general rule: you should only use the newUserId inside the onDataChange or in code that is called from there. For this reason, I recommend making it a local variable in onDataChange instead of a field or otherwise broader scope. For more on why this is, see Is it possible to synchronously load data from Firebase? and Setting Singleton property value in Firebase Listener.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • if I understood correctly you mean to take the variables out of the method and leave only the variable newUserId and remove and the line when i adding the variable inside in Firebase db. But i add this line because I thought when you can add a variable on db with this method but maybe I'm wrong. So how i can create a new user inside real-time db??. Thanks – George Sepetadelis Jan 04 '21 at 07:12
  • Data is only written once you call `setValue`, which you are doing inside `onDataChange` where `newUserId` **is** initialized (as far as I can tell). If you put a breakpoint on `mRef.child("users").child(newUserId);` and run the app in a debugger, you'll see that `newUserId` doesn't have a value, as the `onDataChange` hasn't been run yet. Please read the links I provided in my answer, as I explained it in more detail there. – Frank van Puffelen Jan 04 '21 at 15:31