【问题标题】:How to prevent "Firestore, Provided document path must not be null" error?如何防止“Firestore,提供的文档路径不能为空”错误?
【发布时间】:2019-02-28 16:56:26
【问题描述】:

我有一个 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 用户 id 是否有可能返回 null 或登录成功后,readUserDataFromDatabase 在

之前运行

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

功能?我不知道。谢谢。

编辑 1: 添加了堆栈跟踪。

致命异常:java.lang.RuntimeException:无法启动活动 组件信息{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();
                    }
                }
            });
}

【问题讨论】:

  • 请使用崩溃的详细信息编辑问题。有堆栈跟踪吗?
  • 您好,已使用堆栈跟踪进行编辑。

标签: java android firebase firebase-authentication google-cloud-firestore


【解决方案1】:

对我来说清除缓存很有帮助,因为我刚刚更改了

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

【讨论】:

    【解决方案2】:

    错误消息表明此代码正在将空值传递给 readUserDataFromDatabase

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

    这意味着 UserData.getInstance().getUserId() 正在返回 null。

    这里确实没有足够的代码来完全诊断问题,因为您也没有显示调用 setUser 的内容,但您需要追溯到源头。

    【讨论】:

    • 添加的函数调用 setUser 但 setUser 在其参数为 null 时返回 void。谢谢你的回答。我会尝试改变我缓存用户数据的方式。
    • 谢谢,这对我有用。我只是没有将 intent.putExtra 传递给下一个活动,并在下一个活动中尝试使用它。
    猜你喜欢
    • 1970-01-01
    • 2021-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-15
    • 2021-05-14
    • 1970-01-01
    相关资源
    最近更新 更多