android - 为什么我得到一个空对象引用 documentSnapshot.toObject() 方法?

标签 android firebase google-cloud-firestore

我正在尝试为简单的登录/注册表单添加 firebase 身份验证和 firebase 数据库,但出现崩溃,因为 User currentUser = documentSnapshot.toObject(User.class); 返回一个 null 对象并且我不明白为什么。

这是我的代码 个人资料 Activity :

    package fr.tom_d.growthwatcher;


import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.firestore.DocumentSnapshot;

import fr.tom_d.growthwatcher.api.UserHelper;
import fr.tom_d.growthwatcher.models.User;


public class ProfilActivity extends BaseActivity {

    private static final int UPDATE_USERNAME = 30;
    private FirebaseAuth mAuth;
    private TextView mUsername;
    private EditText mNewUsername;
    private ProgressBar mProgressBar;
    private Button mButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mAuth = FirebaseAuth.getInstance();
        setContentView(R.layout.activity_profil);

        mUsername = findViewById(R.id.profile_tv_username);
        mNewUsername = findViewById(R.id.profile_et_username);
        mProgressBar = findViewById(R.id.profile_progressbar);
        mButton = findViewById(R.id.profile_change_username_btn);

        this.updateUIWhenCreating();

        mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                updateUsernameInFirebase();
            }
        });
    }




    private void updateUIWhenCreating(){

        if (this.getCurrentUser() != null){

            //Get email & username from Firebase
            String username = TextUtils.isEmpty(this.getCurrentUser().getDisplayName()) ? getString(R.string.info_no_username_found) : this.getCurrentUser().getDisplayName();

            //Update views with data
            this.mUsername.setText(username);
        }
        UserHelper.getUser(this.getCurrentUser().getUid()).addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
            @Override
            public void onSuccess(DocumentSnapshot documentSnapshot) {
                User currentUser = documentSnapshot.toObject(User.class);
                String username = TextUtils.isEmpty(currentUser.getUsername()) ? getString(R.string.info_no_username_found) : currentUser.getUsername();
                mNewUsername.setText(username);
            }
        });
    }

    private void updateUsernameInFirebase(){

        String username = this.mNewUsername.getText().toString();

        if (this.getCurrentUser() != null){
            if (!username.isEmpty() &&  !username.equals(getString(R.string.info_no_username_found))){
                UserHelper.updateUsername(username, this.getCurrentUser().getUid()).addOnFailureListener(this.onFailureListener()).addOnSuccessListener(this.updateUIAfterRESTRequestsCompleted(UPDATE_USERNAME));
            }
        }
    }

    private OnSuccessListener<Void> updateUIAfterRESTRequestsCompleted(final int origin){
        return new OnSuccessListener<Void>() {
            @Override
            public void onSuccess(Void aVoid) {
                switch (origin){
                    // 8 - Hiding Progress bar after request completed
                    case UPDATE_USERNAME:
                        mProgressBar.setVisibility(View.INVISIBLE);
                        break;
                }
            }
        };
    }


}

用户:

    package fr.tom_d.growthwatcher.models;

import android.support.annotation.Nullable;

public class User {

    private String mUid;
    @Nullable
    private String mUsername;

    public User() { }

    public User(String uid, String username) {
        mUid = uid;
        mUsername = username;
    }

    // --- GETTERS ---
    public String getUid() { return mUid; }
    public String getUsername() { return mUsername; }

    // --- SETTERS ---
    public void setUsername(String username) { this.mUsername = username; }
    public void setUid(String uid) { this.mUid = uid; }
}

用户帮助器:

package fr.tom_d.growthwatcher.api;

import com.google.android.gms.tasks.Task;
import com.google.firebase.firestore.CollectionReference;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.FirebaseFirestore;

import fr.tom_d.growthwatcher.models.User;

public class UserHelper {

    private static final String COLLECTION_NAME = "users";

    // --- COLLECTION REFERENCE ---


    public static CollectionReference getUsersCollection() {
        return FirebaseFirestore.getInstance().collection(COLLECTION_NAME);
    }

    // --- CREATE ---

    public static Task<Void> createUser(String uid, String username) {
        User userToCreate = new User(uid, username);
        return UserHelper.getUsersCollection().document(uid).set(userToCreate);
    }

    // --- GET ---

    public static Task<DocumentSnapshot> getUser(String uid) {
        return UserHelper.getUsersCollection().document(uid).get();
    }

    // --- UPDATE ---

    public static Task<Void> updateUsername(String username, String uid) {
        return UserHelper.getUsersCollection().document(uid).update("username", username);
    }


    // --- DELETE ---

    public static Task<Void> deleteUser(String uid) {
        return UserHelper.getUsersCollection().document(uid).delete();
    }


}

我还注意到,我的 Firebase 数据库是空的,而当我注册时,如果他通过 Google 登录,则必须使用 Displayname 作为他的电子邮件地址(否则他在 EditText 中指示的昵称)来创建用户。然后我运行我的主要 Activity ,该 Activity 应该在数据库中创建一个用户....

我的mainActivity的代码:

package fr.tom_d.growthwatcher;

import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.design.widget.CoordinatorLayout;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import android.support.design.widget.Snackbar;


import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.jjoe64.graphview.GraphView;
import com.jjoe64.graphview.series.DataPoint;
import com.jjoe64.graphview.series.LineGraphSeries;

import fr.tom_d.growthwatcher.api.UserHelper;

public class MainActivity extends BaseActivity {

    private final static int RC_SIGN_IN = 100;

    private FirebaseAuth mAuth;
    private TextView mMail, mId;
    private EditText mPlantDate, mRelDate, mTempRel;
    private Button mPlantDateBtn, mTempRelBtn, mProfilBtn;
    private GraphView mGraph;
    private DataPoint[] mDataPoint;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        mAuth = FirebaseAuth.getInstance();

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mMail = findViewById(R.id.main_mail);
        mId = findViewById(R.id.main_id);
        //mGraph = findViewById(R.id.main_graph);

        mPlantDate = findViewById(R.id.main_et_date_plant);
        mPlantDateBtn = findViewById(R.id.main_ok_plant_btn);

        mRelDate = findViewById(R.id.main_et_date_rel);
        mTempRel = findViewById(R.id.main_et_temp);
        mTempRelBtn = findViewById(R.id.main_ok_temp_btn);

        mProfilBtn = findViewById(R.id.main_profil_btn);

        //LineGraphSeries<DataPoint> series = new LineGraphSeries<>(mDataPoint);

        mPlantDateBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

            }
        });

        mProfilBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent profileActivity = new Intent(MainActivity.this, ProfilActivity.class);
                startActivity(profileActivity);
            }
        });
    }

    @Override
    public void onStart() {
        super.onStart();
        FirebaseUser currentUser = mAuth.getCurrentUser();
        String vEmail = currentUser.getEmail();
        String vId = currentUser.getProviderId();
        mMail.setText(vEmail);
        mId.setText(vId);
    }


    private void createUserInFirestore(){

        if (this.getCurrentUser() != null){

            String urlPicture = (this.getCurrentUser().getPhotoUrl() != null) ? this.getCurrentUser().getPhotoUrl().toString() : null;
            String username = this.getCurrentUser().getDisplayName();
            String uid = this.getCurrentUser().getUid();

            UserHelper.createUser(uid, username).addOnFailureListener(this.onFailureListener());
        }
    }

    private void handleResponseAfterSignIn(int requestCode, int resultCode, Intent data){

        if (requestCode == RC_SIGN_IN) {
            if (resultCode == RESULT_OK) {
                this.createUserInFirestore();
            } else {
                Toast.makeText(MainActivity.this, "ERREUR CREATION USER FIREBASE",
                        Toast.LENGTH_SHORT).show();
            }
        }
    }
}

注册 Activity :

package fr.tom_d.growthwatcher;

import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.auth.api.signin.GoogleSignIn;
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
import com.google.android.gms.auth.api.signin.GoogleSignInClient;
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
import com.google.android.gms.common.SignInButton;
import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.AuthCredential;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.auth.GoogleAuthProvider;
import com.google.firebase.auth.UserProfileChangeRequest;

import fr.tom_d.growthwatcher.api.UserHelper;

public class RegisterActivity extends BaseActivity {

    private final static String TAG = "RegisterActivity";
    private final static int RC_SIGN_IN = 100;


    private FirebaseAuth mAuth;
    private Button mStartButton;
    private TextView mAppText;
    private EditText mPseudo, mMail, mPassword;
    private boolean isPseudoOk, isPasswordOk, isMailOk;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mAuth = FirebaseAuth.getInstance();

        setContentView(R.layout.activity_register);

        isMailOk = false;
        isPasswordOk = false;
        isPseudoOk = false;


        mAppText = findViewById(R.id.register_app_text);
        mPseudo = findViewById(R.id.register_et_pseudo);
        mPassword = findViewById(R.id.register_et_password);
        mMail = findViewById(R.id.register_et_email);
        mStartButton = findViewById(R.id.register_start_button);

        mPseudo.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                if(s.toString().length() >=3){
                    isPseudoOk=true;
                }
                if (isPseudoOk && isPasswordOk && isMailOk){
                    mStartButton.setEnabled(true);
                }
                else mStartButton.setEnabled(false);
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });

        mPassword.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                if (s.toString().length() >= 5){
                    isPasswordOk = true;
                }
                else isPasswordOk = false;

                if (isPseudoOk && isPasswordOk && isMailOk){
                    mStartButton.setEnabled(true);
                }
                else mStartButton.setEnabled(false);
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });

        mMail.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                if (s.toString().length() >= 5){
                    isMailOk = true;
                }
                else isMailOk = false;

                if (isPseudoOk && isPasswordOk && isMailOk){
                    mStartButton.setEnabled(true);
                }
                else mStartButton.setEnabled(false);
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });

        mStartButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mAuth.createUserWithEmailAndPassword(mMail.getText().toString(), mPassword.getText().toString())
                        .addOnCompleteListener(RegisterActivity.this, new OnCompleteListener<AuthResult>() {
                            @Override
                            public void onComplete(@NonNull Task<AuthResult> task) {
                                if (task.isSuccessful()) {
                                    // Sign in success, update UI with the signed-in user's information
                                    Log.d(TAG, "createUserWithEmail:success");
                                    UserProfileChangeRequest profileUpdates = new UserProfileChangeRequest.Builder()
                                            .setDisplayName(mPseudo.getText().toString()).build();
                                    getCurrentUser().updateProfile(profileUpdates);
                                    createUserInFirestore();
                                    Intent mainActivity = new Intent(RegisterActivity.this, MainActivity.class);
                                    startActivity(mainActivity);

                                } else {
                                    // If sign in fails, display a message to the user.
                                    Log.w(TAG, "createUserWithEmail:failure", task.getException());
                                    Toast.makeText(RegisterActivity.this, "Authentication failed.",
                                            Toast.LENGTH_SHORT).show();
                                }
                            }
                        });
                }
        });
    }

    protected void onStart () {
        super.onStart();
        FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
        if (user != null) {
            Intent mainActivity = new Intent(RegisterActivity.this, MainActivity.class);
            startActivity(mainActivity);
        }
        else {
            // No user is signed in
        }
    }
}

最佳答案

根据toObject()的API文档,如果文档不存在,则返回 null。您应该首先使用 exists() 检查它是否存在。 .

关于android - 为什么我得到一个空对象引用 documentSnapshot.toObject() 方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53788078/

相关文章:

firebase - 如何安装非官方 Firebase 扩展

flutter - 如何在 Flutter 中显示仍在从 Firestore 加载的数据?

Android 键盘调整调整大小

android - 如何从 NDK 获取 IMEI?

android - 两个ListView上面的TextView

javascript - Firestore/Javascript : How to get a document that is named as a date?

javascript - 如何在集合中获取数据firebase集合

android - 如何在Android中使用服务播放声音

java - 如何从 Cloud Firestore 的数组数据字段中获取数据?

swift - Swift Firebase 嵌入 YouTube 视频时遇到问题