解决Firestore注册用户时调用collection方法的空指针异常问题
我已经实现了Firebase的账号注册功能,但注册成功后无法将用户详细信息存入Firestore,出现以下空指针异常:
FATAL EXCEPTION: main
Process: com.example.loginapp, PID: 4826
java.lang.NullPointerException: Attempt to invoke virtual method 'com.google.firebase.firestore.CollectionReference com.google.firebase.firestore.FirebaseFirestore.collection(java.lang.String)' on a null object reference
相关代码如下:
Register.java
package com.example.loginapp; import static android.content.ContentValues.TAG; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import android.content.Intent; import android.os.Bundle; import android.text.TextUtils; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; import com.google.android.gms.tasks.OnCompleteListener; import com.google.android.gms.tasks.Task; import com.google.android.material.textfield.TextInputEditText; import com.google.firebase.auth.AuthResult; import com.google.firebase.auth.FirebaseAuth; import com.google.firebase.auth.FirebaseUser; import com.google.firebase.firestore.DocumentReference; import com.google.firebase.firestore.FirebaseFirestore; import java.util.HashMap; import java.util.Map; public class Register extends AppCompatActivity { TextInputEditText editTextEmail,editTextPassword; EditText nameEditText; Button buttonReg; ProgressBar progressBar; TextView textView; FirebaseAuth mAuth; FirebaseFirestore fStore; public void onStart() { super.onStart(); // Check if user is signed in (non-null) and update UI accordingly. FirebaseUser currentUser = mAuth.getCurrentUser(); if(currentUser != null){ Intent intent = new Intent(getApplicationContext(), MainActivity.class); startActivity(intent); finish(); } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_register); editTextEmail = findViewById(R.id.email); editTextPassword = findViewById(R.id.password); nameEditText = findViewById(R.id.regi_name); buttonReg = findViewById(R.id.btn_register); progressBar = findViewById(R.id.progressBar); mAuth = FirebaseAuth.getInstance(); textView = findViewById(R.id.loginNow); textView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(getApplicationContext(), Login.class); startActivity(intent); finish(); } }); buttonReg.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { progressBar.setVisibility(View.VISIBLE); String email, password; email = String.valueOf(editTextEmail.getText()); password = String.valueOf(editTextPassword.getText()); if (TextUtils.isEmpty(email)){ Toast.makeText(Register.this, "Enter Email | NO Email", Toast.LENGTH_SHORT).show(); return; } if (TextUtils.isEmpty(password)){ Toast.makeText(Register.this, "Enter Password", Toast.LENGTH_SHORT).show(); return; } mAuth.createUserWithEmailAndPassword(email, password) .addOnCompleteListener(new OnCompleteListener<AuthResult>() { @Override public void onComplete(@NonNull Task<AuthResult> task) { progressBar.setVisibility(View.GONE); if (task.isSuccessful()) { Toast.makeText(Register.this, "Account successfully created", Toast.LENGTH_SHORT).show(); // save the user details to DB FirebaseUser user = mAuth.getCurrentUser(); FirebaseUser currentFirebaseUser = FirebaseAuth.getInstance().getCurrentUser() ; DocumentReference df = fStore.collection("User").document(user.getUid()); Map<String, Object>userInfo = new HashMap<>(); userInfo.put("Name",nameEditText.getText().toString()); userInfo.put("UserEmail",editTextEmail.getText().toString()); // access level userInfo.put("isAdmin", "0"); df.set(userInfo); Intent intent = new Intent(getApplicationContext(), Login.class); startActivity(intent); finish(); } else { // If sign in fails, display a message to the user. Log.w(TAG, "createUserWithEmail:failure", task.getException()); Toast.makeText(Register.this, "Authentication failed.", Toast.LENGTH_SHORT).show(); } } }); } }); } }
activity_register.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="15dp" android:gravity="center" tools:context=".Register"> <TextView android:text="@string/register" android:textSize="28sp" android:textStyle="bold" android:gravity="center" android:layout_marginBottom="15dp" android:layout_width="match_parent" android:layout_height="wrap_content"/> <com.google.android.material.textfield.TextInputLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <com.google.android.material.textfield.TextInputEditText android:id="@+id/regi_name" android:hint="@string/name" android:layout_width="match_parent" android:layout_height="wrap_content"/> </com.google.android.material.textfield.TextInputLayout> <com.google.android.material.textfield.TextInputLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <com.google.android.material.textfield.TextInputEditText android:id="@+id/email" android:hint="@string/email" android:layout_width="match_parent" android:layout_height="wrap_content"/> </com.google.android.material.textfield.TextInputLayout> <com.google.android.material.textfield.TextInputLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <com.google.android.material.textfield.TextInputEditText android:id="@+id/password" android:hint="@string/password" android:layout_width="match_parent" android:layout_height="wrap_content"/> </com.google.android.material.textfield.TextInputLayout> <ProgressBar android:id="@+id/progressBar" android:visibility="gone" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <Button android:id="@+id/btn_register" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/btn_register" android:layout_margin="10dp"/> <TextView android:id="@+id/loginNow" android:text="@string/click_to_login" android:textSize="20sp" android:textStyle="bold" android:gravity="center" android:layout_width="match_parent" android:layout_height="wrap_content"/> </LinearLayout>
解决方法
初始化FirebaseFirestore实例
空指针的核心原因是你只声明了FirebaseFirestore fStore;但没有初始化。在onCreate方法里,给mAuth初始化之后添加一行代码:fStore = FirebaseFirestore.getInstance();位置就在
mAuth = FirebaseAuth.getInstance();下方。简化冗余代码
你在保存用户信息时重复获取了FirebaseUser实例(user和currentFirebaseUser),可以删掉其中一个,比如保留FirebaseUser user = mAuth.getCurrentUser();即可。添加数据保存结果监听
建议给df.set(userInfo)添加完成监听,以便知道用户信息是否成功存入Firestore,代码示例:df.set(userInfo).addOnCompleteListener(new OnCompleteListener<Void>() { @Override public void onComplete(@NonNull Task<Void> task) { if(task.isSuccessful()){ Toast.makeText(Register.this, "用户信息保存成功", Toast.LENGTH_SHORT).show(); }else{ Toast.makeText(Register.this, "用户信息保存失败: "+task.getException().getMessage(), Toast.LENGTH_SHORT).show(); } } });
内容的提问来源于stack exchange,提问作者Noor

