【问题标题】:Error while performing compound queries in firestore在 Firestore 中执行复合查询时出错
【发布时间】:2021-10-01 06:33:33
【问题描述】:

我想在 firestore 中执行复合查询,我想获取字段 bloodgroup 等于 A+ 且字段 createdBy 不等于 email 的所有文档。此电子邮件是登录用户的电子邮件。当我执行查询时,我得到 NullPointerException。如何正确执行查询 021-07-24 19:50:24.746 17550-17550/com.example.bloodbankcompany E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.bloodbankcompany, PID: 17550 java.lang.NullPointerExceptionatcom.example.bloodbankcompany.UserlistActivity$EventChangeListener3$1.onEvent(UserlistActivity.kt:217) 我将文档快照存储在userArrayList 数组中。如果没有 whereNotEqualTo 查询,我将获得输出,其中我的文档在 recyclerview 中列出。

private fun EventChangeListener2(){

        val sharedPreferences1 = getSharedPreferences("email", Context.MODE_PRIVATE)
        val email: String? = sharedPreferences1.getString("email","null")?.trim()

        Toast.makeText(this, "ssrae$email", Toast.LENGTH_SHORT ).show()

        mFireStore.collection("applicationForm").whereNotEqualTo("createdBy",email).whereEqualTo("bloodgroup","A+").addSnapshotListener(object : EventListener<QuerySnapshot>{
            override fun onEvent(value: QuerySnapshot?, error: FirebaseFirestoreException?) {
                if (error!= null){
                    Log.e("firestore error", error.message.toString())
                }

                for(dc: DocumentChange in value?.documentChanges!!){
                    if (dc.type== DocumentChange.Type.ADDED){


                        userArrayList.add(dc.document.toObject(User1::class.java))
                        var number=userArrayList
                        var number1 =userArrayList

                    }
//                    Toast.makeText(applicationContext,userArrayList.toString(), Toast.LENGTH_SHORT).show()

                }
                myAdapter.notifyDataSetChanged()
            }

        })

    }

【问题讨论】:

    标签: firebase kotlin google-cloud-firestore nullpointerexception


    【解决方案1】:

    好吧,我已经编辑了你的一些代码,如果它仍然不起作用,请添加评论。

    另外,下面评论了有关更改的说明。

    private fun EventChangeListener2() {
    
            val sharedPreferences1 = getSharedPreferences("email", Context.MODE_PRIVATE)
            val email: String? = sharedPreferences1.getString("email", "null")?.trim()
    
            Log.d("firestore email", email.toString())
    
            Toast.makeText(this, "ssrae$email", Toast.LENGTH_SHORT).show()
    
            // try and catch will avoid your app to crash.
            try {
    
                //ref
                var ref = mFireStore.collection("applicationForm")
                    .whereEqualTo("bloodgroup", "A+")
    
    
                /**
                 *  I believe since your email is of type nullable and there may be
                 *  maybe a chance that email is null and is given to whereNotEqualTo
                 *  I am just making an assumption here since I don't know what you
                 *  recieve from sharedPreferences and whether it is null or not
                 *
                 *  So, what I have done here is,
                 *  firstly, I have split the firestore call into 2 parts and
                 *  Secondly, I have a null-check for email, if it is
                 *  not-null ref will also include this query
                 *
                 */
                //null Check for email
                if (email != null) ref = ref.whereNotEqualTo("createdBy", email)
    
                // Snapshot Listener
                ref.addSnapshotListener(object : EventListener<QuerySnapshot> {
                    override fun onEvent(value: QuerySnapshot?, error: FirebaseFirestoreException?) {
                        if (error != null) {
                            Log.e("firestore error", error.message.toString())
                        }
    
                        for (dc: DocumentChange in value?.documentChanges!!) {
                            if (dc.type == DocumentChange.Type.ADDED) {
    
    
                                userArrayList.add(dc.document.toObject(User1::class.java))
                                var number = userArrayList
                                var number1 = userArrayList
    
                            }
    //                    Toast.makeText(applicationContext,userArrayList.toString(), Toast.LENGTH_SHORT).show()
    
                        }
                        myAdapter.notifyDataSetChanged()
                    }
    
                })
            } catch (e: Exception) {
                Log.e("firestore error", "Error", e)
            }
        }
    

    编辑: 根据 firebase 文档,

    https://firebase.google.com/docs/firestore/query-data/indexing#exemptions

    如果您尝试使用未映射到现有索引的范围子句进行复合查询,则会收到错误消息。错误消息包含在 Firebase 控制台中创建缺失索引的直接链接。

    【讨论】:

    • 当我单独使用查询 whereEqualTo 和单独使用 whereNotEqualTo 时,我得到了输出。但是当我将两个查询放在一起 .whereEqualTo.whereNotEqualTo 时,我得到了错误。
    • 你能不能用这个替换你的代码并在它失败之前发送 logcat 值。
    • 所以这里发生了什么,即上面在答案中提供的代码是,如果电子邮件不为空,它将结合whereEqualTowhereNotEqualTo 否则只有whereEqualTo 会运行
    • 2021-07-24 23:01:45.770 14803-14803/com.example.bloodbankcompany E/firestore error: FAILED_PRECONDITION: The query requires an index. You can create it here: https://console.firebase.google.com/v1/r/project/fir-2company/firestore/indexes?create_composite= 2021-07-24 23:01:45.771 14803-14803/com.example.bloodbankcompany E/AndroidRuntime: FATAL EXCEPTION: PID: 14803 java.lang.NullPointerException
    • 所以在您的错误复制中生成了一个链接并将其粘贴“https:// .......... 8QAQ”
    猜你喜欢
    • 2020-05-06
    • 2020-09-01
    • 1970-01-01
    • 2018-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多