简体   繁体   English

Android Studio Kotlin Null 更新 Firestore 数据库时出现指针异常

[英]Android Studio Kotlin Null Pointer Exception while updating Firestore Database

I've recently stumbled upon a runtime error that crashes my application for whatever reason and I cannot get to the bottom of it.我最近偶然发现了一个运行时错误,无论出于何种原因导致我的应用程序崩溃,我无法深入了解它。 Basically I am updating user profile data by storing it in a hashmap.基本上,我通过将用户配置文件数据存储在 hashmap 中来更新它。 This is what the user class looks like:这是用户 class 的样子:

@Parcelize
data class User(
    val id: String = "",
    val firstName: String = "",
    val lastName: String = "",
    val email: String = "",
    val image: String = "",
    val mobile: Long = 0,
    val gender: String = "",
    val profileCompleted: Int = 0): Parcelable

In an activity I called UserProfileActivity I store the mobile and gender into a hashmap, then call the Firebase function to update the Firestore Database.在我称为 UserProfileActivity 的活动中,我将手机和性别存储到 hashmap,然后调用 Firebase function 以更新 Firestore 数据库。 Here is a method of the activity.这是活动的方法。 When the button "submit" is clicked, this code runs:单击“提交”按钮时,此代码运行:

btn_submit.setOnClickListener {
            if(validateUserProfileDetails()){  //checks if entered credentials are valid
                val userHashMap = HashMap<String, Any>()  //creates the hashmap

                val mobileNumber = et_mobile_number.text.toString().trim { it <= ' ' }

                val gender = if (rb_male.isChecked) {  //these are radio buttons, only 1 clicked
                    Constants.MALE
                } else {
                    Constants.FEMALE
                }

                userHashMap[Constants.MOBILE] = mobileNumber.toLong()  //storing info in hashmap

                userHashMap[Constants.GENDER] = gender

                showProgressDialog(resources.getString(R.string.please_wait))  //starting a progress dialog

                FirestoreClass().updateUserProfileData(  //method in FirestoreClass 
                    this, userHashMap
                )
            }
        }

Now the called method that communicates with the database:现在调用与数据库通信的方法:

fun updateUserProfileData(activity: Activity, userHashMap: HashMap<String, Any>) {
        mFireStore.collection(Constants.USERS)  // collection named "users"
            .document(getCurrentUserID())  //getCurrentUserID() just gets the current user id 
            .update(userHashMap)  // hashmap used to update the user
            .addOnSuccessListener {
                when (activity) {
                    is UserProfileActivity -> {
                        activity.userProfileUpdateSuccess() //this just hides the progress dialog and finishes the activity in the UserProfileActivity
                    }
                }
            }
            .addOnFailureListener { e ->
                when (activity) {
                    is UserProfileActivity -> {
                        activity.hideProgressDialog()
                    }
                }
            }


}

But I am getting this error:但我收到此错误:

2021-12-27 02:35:38.727 14960-14960/com.example.myshopapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.myshopapp, PID: 14960
java.lang.NullPointerException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkNotNullParameter, parameter it
    at com.example.myshopapp.firestore.FirestoreClass.updateUserProfileData$lambda-2(Unknown Source:7)
    at com.example.myshopapp.firestore.FirestoreClass.$r8$lambda$vs4EuaGwStcL-i3lXRUecduDHWM(Unknown Source:0)
    at com.example.myshopapp.firestore.FirestoreClass$$ExternalSyntheticLambda4.onSuccess(Unknown Source:4)
    at com.google.android.gms.tasks.zzm.run(com.google.android.gms:play-services-tasks@@18.0.0:1)
    at android.os.Handler.handleCallback(Handler.java:938)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:223)
    at android.app.ActivityThread.main(ActivityThread.java:7656)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

I have absolutely no clue where the null pointer exception is occuring... And funnily enough (this is important), the database DOES get updated properly so why is it crashing??我完全不知道 null 指针异常发生在哪里......而且有趣的是(这很重要),数据库确实得到了正确更新,为什么它会崩溃? Any help would be much appreciated.任何帮助将非常感激。 :) :)

This specific error has been showing up a lot lately, and seems to be due to an inconsistent nullability annotation in Firebase listeners.这个特定的错误最近出现了很多,似乎是由于 Firebase 侦听器中的可空性注释不一致。

The signature for addOnSuccessListener is (where TResult is Void for a document update call): addOnSuccessListener的签名是(其中 TResult 对于文档update调用是无效的):

@NonNull
public abstract Task<TResult> addOnSuccessListener(@NonNull OnSuccessListener<? super TResult> var1);

And the interface for the success listener is currently (without a nullability annotation on the supplied parameter):成功侦听器的接口当前是(在提供的参数上没有可空性注释):

public interface OnSuccessListener<TResult> {
    void onSuccess(TResult var1);
}

However, when adding a listener in Kotlin it infers a non-null type for it ( Void not Void? ).但是,当在 Kotlin 中添加侦听器时, it会为其推断非空类型( Void not Void? )。 This means if Firestore returns a null result (which would not be uncommon for a Void argument from java), it will raise the error you showed when it is cast to a non-null parameter.这意味着如果 Firestore 返回 null 结果(这对于来自 java 的Void参数并不少见),它将引发您在将其转换为非空参数时显示的错误。 The solution is to specifically set the type to nullable, so to change解决方法是专门设置类型为nullable,所以要改

.addOnSuccessListener { 
    println("Updated doc")
}

to

.addOnSuccessListener { _: Void? ->
    println("Updated doc")
}

In contrast, the interface for onFailureListener is a Non-Null non void argument, so there shouldn't be an issue there.相反, onFailureListener的接口是一个 Non-Null 非 void 参数,所以那里不应该有问题。

public interface OnFailureListener {
    void onFailure(@NonNull Exception var1);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM