在 Firestore 中执行复合查询时出错
Posted
技术标签:
【中文标题】在 Firestore 中执行复合查询时出错【英文标题】:Error while performing compound queries in 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, "s-s-rae$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()
)
【问题讨论】:
【参考方案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, "s-s-rae$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 值。
所以这里发生了什么,即上面在答案中提供的代码是,如果电子邮件不为空,它将结合whereEqualTo
和whereNotEqualTo
否则只有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”以上是关于在 Firestore 中执行复合查询时出错的主要内容,如果未能解决你的问题,请参考以下文章
isEqual to operator 在 Flutter Firestore 中无法正常工作
在颤动中使用 REST api 将列表数据发送到云 Firestore 时出错