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

时间:2018-12-14 23:17:04

标签: android firebase google-cloud-firestore

我正在尝试为简单的登录/注册表单添加firebase auth和firebase数据库,但是由于User currentUser = documentSnapshot.toObject(User.class);返回空对象而导致崩溃,我不知道为什么。

这是我的代码 ProfileActivity:

    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; }
}

UserHelper:

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中指示的昵称。然后我运行我的主要活动,该活动应该在数据库中创建一个用户....

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();
            }
        }
    }
}

RegisterActivity:

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
        }
    }
}

1 个答案:

答案 0 :(得分:1)

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