Как предотвратить ошибку «Firestore, предоставленный путь к документу не должен быть нулевым»? - PullRequest
0 голосов
/ 25 сентября 2018

У меня есть приложение для Android, у которого сейчас ~ 2k активных пользователей.Он использует базу данных Firebase Firestore для сохранения пользовательских данных и прочего.Но недавно я получил сообщения об ошибках и сбоях из моей функции readUserDataFromDatabase:

    private void readUserDataFromDatabase(String uid) {
    db.collection(Constants.PARAM_USERS)
            .document(uid) // (MainActivity.java:215)This is where the crash happens 
            .get()
            .addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
                @Override
                public void onSuccess(DocumentSnapshot documentSnapshot) {
                    UserData userData = documentSnapshot.toObject(UserData.class);
                    if (userData == null) 
                        return;

                    tvName.setText(getString(R.string.welcome, userData.getName()));

                    Picasso
                            .get()
                            .load(userData.getPhotoUrl())
                            .placeholder(getResources().getDrawable(R.drawable.place_holder))
                            .transform(new RoundedCornersTransform())
                            .into(ivPhoto);

                    UserData.getInstance().setCredit(userData.getCredit());
                    UserData.getInstance().setPhotoUrl(userData.getPhotoUrl());
                    UserData.getInstance().setName(userData.getName());

                    if (userData.getInstanceId() != null) {
                        UserData.getInstance().setInstanceId(userData.getInstanceId());
                    }
                }
            });

}

Эта функция запускается после перенаправления из входа в систему с успешным процессом входа в систему:

private void setUser(final FirebaseUser user) {
    if (user == null)
        return;

    UserData.getInstance().setUserId(user.getUid());// I'm using this Uid for create node for user.
    DocumentReference docRef = db.collection(Constants.PARAM_USERS).document(user.getUid());

    docRef
            .get()
            .addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
                @Override
                public void onSuccess(DocumentSnapshot documentSnapshot) {
                    UserData userData = documentSnapshot.toObject(UserData.class);
                    if (userData == null) {
                        createUser(user);
                    } else {
                        redirectToHome(); //login succeed
                    }
                }
            }).addOnFailureListener(new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception e) {

        }
    });
}

И вызова функции readUserDataFromDatabaseнапример, из-за перенаправленной активности:

 readUserDataFromDatabase(UserData.getInstance().getUserId());

Частота сбоев составляет около% 1, но я все еще не вижу, что мне здесь не хватает.Существует ли вероятность того, что идентификатор пользователя firebase вернет значение null или после успешного входа в систему readUserDataFromDatabase будет запущен перед функцией

UserData.getInstance().setUserId(user.getUid());

?Я не знаю.Спасибо.

Редактировать 1: Добавлена ​​трассировка стека.

Неустранимое исключение: java.lang.RuntimeException: Невозможно запустить действие ComponentInfo {com.alialacan.kpss / com.alialacan.kpss.MainActivity}: java.lang.NullPointerException: указанный путь к документу не должен быть пустым.в android.app.ActivityThread.performLaunchActivity (ActivityThread.java:2781) в android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2859) в android.app.ActivityThread.-wrap11 (неизвестный источник) в android.app.ActivityThread $H.handleMessage (ActivityThread.java:1592) на android.os.Handler.dispatchMessage (Handler.java:106) на android.os.Looper.loop (Looper.java:164) на android.app.ActivityThread.main (ActivityThread.java: 6518) на java.lang.reflect.Method.invoke (Method.java) на com.android.internal.os.RuntimeInit $ MethodAndArgsCaller.run (RuntimeInit.java:438) на com.android.internal.os.ZygoteInit.main (ZygoteInit.java:807)

Caused by java.lang.NullPointerException: Provided document path must not be null.
       at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:228)
       at com.google.firebase.firestore.CollectionReference.document(SourceFile:90)
       at com.alialacan.kpss.MainActivity.readUserDataFromDatabase(MainActivity.java:215)
       at com.alialacan.kpss.MainActivity.onCreate(MainActivity.java:114)
       at android.app.Activity.performCreate(Activity.java:7013)
       at android.app.Activity.performCreate(Activity.java:7004)
       at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1215)
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2734)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2859)
       at android.app.ActivityThread.-wrap11(Unknown Source)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1592)
       at android.os.Handler.dispatchMessage(Handler.java:106)
       at android.os.Looper.loop(Looper.java:164)
       at android.app.ActivityThread.main(ActivityThread.java:6518)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

Редактировать 2: Здесь, где setUser вызывает функцию:

    @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    callbackManager.onActivityResult(requestCode, resultCode, data);

    if (requestCode == Constants.RC_SIGN_IN) {
        GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
        if (result.isSuccess()) {
            GoogleSignInAccount account = result.getSignInAccount();
            firebaseAuthWithGoogle(account);
        } else {
            Toast.makeText(LoginActivity.this, R.string.error_google_login,
                    Toast.LENGTH_SHORT).show();
            hideProgress();
        }
    }
}

 private void handleFacebookAccessToken(AccessToken token) {
    Log.d("", "handleFacebookAccessToken:" + token);

    AuthCredential credential = FacebookAuthProvider.getCredential(token.getToken());
    auth.signInWithCredential(credential)
            .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    if (task.isSuccessful()) {                          
                        Log.d("", "signInWithCredential:success");
                        user = auth.getCurrentUser();
                        setUser(user);
                    } else {
                        setUser(null);
                        Log.w("", "signInWithCredential:failure", task.getException());
                        Toast.makeText(LoginActivity.this, R.string.error_email_already_exist,
                                Toast.LENGTH_SHORT).show();
                        hideProgress();
                    }
                }
            });
}

 private void firebaseAuthWithGoogle(GoogleSignInAccount acct) {
    AuthCredential credential = GoogleAuthProvider.getCredential(acct.getIdToken(), null);
    auth.signInWithCredential(credential)
            .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    if (task.isSuccessful()) {
                        FirebaseUser user = auth.getCurrentUser();
                        setUser(user);
                    } else {
                        Toast.makeText(LoginActivity.this, R.string.error_google_login,
                Toast.LENGTH_SHORT).show();
                        setUser(null);
                        hideProgress();
                    }
                }
            });
}

Ответы [ 2 ]

0 голосов
/ 11 апреля 2019

Для меня очистка кеша помогла, так как я только что изменил

collection("Posts").orderBy("timestamp",Query.Direction.DESCENDING) на collection("Posts").orderBy("like_count",Query.Direction.DESCENDING)

0 голосов
/ 25 сентября 2018

В сообщениях об ошибках говорится, что этот код передает нулевое значение в readUserDataFromDatabase

readUserDataFromDatabase(UserData.getInstance().getUserId());

Это означает, что UserData.getInstance().getUserId() возвращает нулевое значение.

На самом деле недостаточно кода для полнойдиагностируйте проблему, так как вы также не показываете, что звонит setUser, но вам нужно отследить это до источника.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...