androidfirebase

'java.lang.String com.google.firebase.auth.FirebaseUser.getEmail()' on a null object reference


The app crashes when the user presses the sign-in button and only if the details he wrote down in the edit texts are correct by the firebaseAuth. reopening the app will make the app behave as nothing happened and the user will be signed in.

Here's the code:

public class LoginActivity extends Activity {
    
    private Button btnRegister, btnSignIn, btnForgot;
    private EditText etPhone, etPassword;

    private ProgressBar mprogressBar;

    private FirebaseAuth fbAuth;
    private FirebaseUser fbUser;

    private FirebaseFirestore db;
    private DocumentReference uDocRef;
    private CollectionReference uColctRef;

    SharedPreferences sharedPreferences;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        btnRegister = findViewById(R.id.btnRegister);
        btnSignIn = findViewById(R.id.btnSignIn);
        btnForgot = findViewById(R.id.btnForgot);
        etPhone = findViewById(R.id.etPhone);
        etPassword = findViewById(R.id.etPassword);
        mprogressBar = findViewById(R.id.mprogressBar);

        fbAuth = FirebaseAuth.getInstance();
        fbUser = fbAuth.getCurrentUser();

        initFirebase();
    }

    private void initFirebase() {
        db = FirebaseFirestore.getInstance();
        uColctRef = db.collection(UserFirebase.UsersCollection);
        if (fbUser != null)
        {
            Toast.makeText(this, "User already logged in: " + fbUser.getEmail(), Toast.LENGTH_LONG).show();
            refreshListAndSubscribe();
            Intent zone = new Intent(this, ZoneActivity.class);
            startActivity(zone);
        }
    }

    private void refreshListAndSubscribe() {
        uColctRef
                .addSnapshotListener(new EventListener<QuerySnapshot>() {
                    @Override
                    public void onEvent(@Nullable QuerySnapshot result,
                                        @Nullable FirebaseFirestoreException e) {
                        if (e != null) {
                            Log.e("FirebaseDemo-Query", "Listen failed", e);
                            e.printStackTrace();
                            return;
                        }
                        Log.i("FirebaseDemo-Query", "Listen succeded");
                        checklist(result);
                    }
                });

    }

    private void checklist(QuerySnapshot result) {
        String email;
        boolean isApproved;
        sharedPreferences = getSharedPreferences("SaveData", Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        for (QueryDocumentSnapshot document : result) {
            email = document.get(UserFirebase.email).toString();
            if (etPhone.getText().toString().trim().equals(email))
            {
                String branchCode = String.valueOf(document.get(UserFirebase.branchCode));
                String role = document.get(UserFirebase.roleType).toString();
                isApproved = Boolean.parseBoolean(document.get(UserFirebase.isApproved).toString());
                editor.putString("myBranch", branchCode);
                editor.putString("myRole", role);
                editor.putString("myEmail", email);
                editor.putBoolean("isApproved", isApproved);
                editor.apply();
            }
            if (fbUser != null)
            {
                if (fbUser.getEmail().equals(email))
                {
                    String branchCode = String.valueOf(document.get(UserFirebase.branchCode));
                    String role = document.get(UserFirebase.roleType).toString();
                    isApproved = Boolean.parseBoolean(document.get(UserFirebase.isApproved).toString());
                    editor.putString("myBranch", branchCode);
                    editor.putString("myRole", role);
                    editor.putString("myEmail", email);
                    editor.putBoolean("isApproved", isApproved);
                    editor.apply();
                }
            }
        }
    }

    public void onSign(View v)
    {
       if (isEmpty())
            return;
            inProgress(true);
                fbAuth.signInWithEmailAndPassword(etPhone.getText().toString().trim(), etPassword.getText().toString())
               .addOnSuccessListener(new OnSuccessLstnr("User Signed In", true))
                .addOnFailureListener(new OnFailLstnr("Sign-in failed!"));
    }

    public void setPassword(View v)
    {
        Intent pass = new Intent(this, PasswordActivity.class);
        startActivity(pass);
    }

    public void onRegister(View v)
    {
        Intent auth = new Intent (this, RegisterActivity.class);
        startActivity(auth);
    }

    private void inProgress(boolean inProgress)
    {
        if (inProgress)
        {
            mprogressBar.setVisibility(View.VISIBLE);
            btnSignIn.setEnabled(false);
            btnRegister.setEnabled(false);
            btnForgot.setEnabled(false);
        }
        else
        {
            mprogressBar.setVisibility(View.INVISIBLE);
            btnSignIn.setEnabled(true);
            btnRegister.setEnabled(true);
            btnForgot.setEnabled(true);
        }
    }

    private boolean isEmpty()
    {
        if (TextUtils.isEmpty(etPhone.getText().toString()))
        {
            etPhone.setError("REQUIRED!");
            return true;
        }
        if (TextUtils.isEmpty(etPassword.getText().toString()))
        {
            etPassword.setError("REQUIRED!");
            return true;
        }
        return false;
    }

    private class OnFailLstnr implements OnFailureListener
    {
        String msg;
        public OnFailLstnr(String _msg)
        {
            this.msg = _msg;
        }

        @Override
        public void onFailure(@NonNull Exception e)
        {
            inProgress(false);
            Toast.makeText(LoginActivity.this, msg, Toast.LENGTH_SHORT).show();
        }
    }

    public class OnSuccessLstnr implements OnSuccessListener<AuthResult>
    {
        String msg;
        boolean open;

        OnSuccessLstnr(String _msg, boolean _open)
        {
            this.msg = _msg;
            this.open = _open;
        }

        @Override
        public void onSuccess(AuthResult authResult)
        {
            Toast.makeText(LoginActivity.this, msg, Toast.LENGTH_LONG).show();
            inProgress(false);
            if (open)
            {
                refreshListAndSubscribe();
                Intent in = new Intent(LoginActivity.this, ZoneActivity.class);
                startActivity(in);
                finish();
            }
        }
    }

The Logcat:

java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.google.firebase.auth.FirebaseUser.getEmail()' on a null object reference
        at com.a.shon.scoutszone2.Activities.LoginActivity.checklist(LoginActivity.java:127)
        at com.a.shon.scoutszone2.Activities.LoginActivity.access$000(LoginActivity.java:42)
        at com.a.shon.scoutszone2.Activities.LoginActivity$1.onEvent(LoginActivity.java:101)
        at com.a.shon.scoutszone2.Activities.LoginActivity$1.onEvent(LoginActivity.java:91)

I've tried fixing it using answers to some similar questions that were already posted in the site, but it didn't really change or fix the problem.

I would like to get help with solving this issue out and every help would be appreciated by A LOT!

Thanks in advance!


Solution

  • Found a solution, Seems like dealing with Already authenticated users (Users who already logged in, just reopening the app) and users who are just logged out from the app in one method (Check the - private void checklist(QuerySnapshot result), to understand what I'm talking about) is quite a messy way to deal with it, and making it really buggy.

    The solution: In InitFirebase() change the calling of refreshListAndSubscribe(); to a different new method, i called it refreshExistingUser(), its the same code as refreshListAndSubscribe() the only part which is different between the two is the calling for the second method at the end of them. Ill Add here a part of the code to make it simpler to understand:

    private void initFirebase() {
        db = FirebaseFirestore.getInstance();
        uColctRef = db.collection(UserFirebase.UsersCollection);
        if (fbUser != null)
        {
            Toast.makeText(this, "User already logged in: " + fbUser.getEmail(), Toast.LENGTH_LONG).show();
            refreshExistingUser();
            Intent zone = new Intent(this, ZoneActivity.class);
            startActivity(zone);
        }
    }
    
    private void refreshListAndSubscribe() {
        uColctRef
                .addSnapshotListener(new EventListener<QuerySnapshot>() {
                    @Override
                    public void onEvent(@Nullable QuerySnapshot result,
                                        @Nullable FirebaseFirestoreException e) {
                        if (e != null) {
                            Log.e("FirebaseDemo-Query", "Listen failed", e);
                            e.printStackTrace();
                            return;
                        }
                        Log.i("FirebaseDemo-Query", "Listen succeded");
                        checklist(result);
                    }
                });
    
    }
    
    private void checklist(QuerySnapshot result) {
        String email;
        boolean isApproved;
        sharedPreferences = getSharedPreferences("SaveData", Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        for (QueryDocumentSnapshot document : result) {
            email = document.get(UserFirebase.email).toString();
            if (etPhone.getText().toString().trim().equals(email))
            {
                String branchCode = String.valueOf(document.get(UserFirebase.branchCode));
                String role = document.get(UserFirebase.roleType).toString();
                isApproved = Boolean.parseBoolean(document.get(UserFirebase.isApproved).toString());
                editor.putString("myBranch", branchCode);
                editor.putString("myRole", role);
                editor.putString("myEmail", email);
                editor.putBoolean("isApproved", isApproved);
                editor.apply();
            }
        }
    }
    
    private void refreshExistingUser() {
        uColctRef
                .addSnapshotListener(new EventListener<QuerySnapshot>() {
                    @Override
                    public void onEvent(@Nullable QuerySnapshot result,
                                        @Nullable FirebaseFirestoreException e) {
                        if (e != null) {
                            Log.e("FirebaseDemo-Query", "Listen failed", e);
                            e.printStackTrace();
                            return;
                        }
                        Log.i("FirebaseDemo-Query", "Listen succeded");
                        checkuser(result);
                    }
                });
    }
    
    private void checkuser(QuerySnapshot result) {
        String email;
        boolean isApproved;
        sharedPreferences = getSharedPreferences("SaveData", Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        for (QueryDocumentSnapshot document : result) {
            email = document.get(UserFirebase.email).toString();
            if (fbUser.getEmail().equals(email)) { //When the user isnt == null (Reopening the app and such)
                String branchCode = String.valueOf(document.get(UserFirebase.branchCode));
                String role = document.get(UserFirebase.roleType).toString();
                isApproved = Boolean.parseBoolean(document.get(UserFirebase.isApproved).toString());
                editor.putString("myBranch", branchCode);
                editor.putString("myRole", role);
                editor.putString("myEmail", email);
                editor.putBoolean("isApproved", isApproved);
                editor.apply();
            }
        }
    }