如何将复杂的Firestore查询卸载到Firebase云函数中,并在iOS/Swift客户端上解析结果?

如何将复杂的Firestore查询卸载到Firebase云函数中,并在iOS/Swift客户端上解析结果?,firebase,google-cloud-firestore,google-cloud-functions,Firebase,Google Cloud Firestore,Google Cloud Functions,因此,目前,我的客户机(iOS/Swift)正在通过过滤whereField(…)获取文档,然后根据其他几个字段进一步过滤结果。这意味着一些对象被获取,然后被丢弃,浪费了宝贵的资源和带宽 我可以在firestore云函数上进行这种复杂的过滤,而不是以某种方式将过滤结果解析到客户端上的同一firestore对象中吗?要清楚,我知道如何编写获取和返回文档的云函数,我更感兴趣的是了解到客户端的传输方法 提供某些上下文的代码段: static func unmatchedChatsHelper(光标:A

因此,目前,我的客户机(iOS/Swift)正在通过过滤
whereField(…)
获取文档,然后根据其他几个字段进一步过滤结果。这意味着一些对象被获取,然后被丢弃,浪费了宝贵的资源和带宽

我可以在firestore云函数上进行这种复杂的过滤,而不是以某种方式将过滤结果解析到客户端上的同一firestore对象中吗?要清楚,我知道如何编写获取和返回文档的云函数,我更感兴趣的是了解到客户端的传输方法

提供某些上下文的代码段:

static func unmatchedChatsHelper(光标:Any?,承诺:@escaping(Result)->Void){
让earliestEventTime=Date()
//(1)在后端完成筛选。
var query=Firestore.Firestore().collection(“聊天”)
.whereField(“eventTime”,大于:earliestEventTime)
.订单(由:“事件时间”)
.顺序(按“创建数据”,降序:真)
如果让光标=光标作为文档快照{
query=query.start(afterDocument:cursor)
}
query.getDocuments{(querySnapshot,错误)位于
guard let querySnapshot=querySnapshot else{
fatalError(“查询快照失败:\(错误?.localizedDescription??“无错误”))
}
让transformedModels=querySnapshot.documents.compactMap{(chatQueryDocumentSnapshot)->ChatModelFirebase?在
做{
返回并尝试chatQueryDocumentSnapshot.data(as:ChatModelFirebase.self)!
}捕捉错误{
日志事件(AnalyticsEventDidDropDocument[
“文档id”:chatQueryDocumentSnapshot.documentID
],错误)
归零
}
}
让我=Auth.Auth().currentUser!.uid
//(2)在客户端完成过滤!这意味着不必要地检索了一些聊天记录。
让unmatchedChats=transformedModels.filter{
!$0。参与者。包含(我)
&&$0.00参与者<6
&&!$0。下线参与者。包含(我)
&&$0.isDebug==DebugGating.isDebugBuild()
}
让cursor=querySnapshot.documents.last
承诺(.success(unmatchedchatscorresponse(型号:unmatchedChats,游标:游标as Any)))
}
}
我有三个选择:

  • [我的选择/最佳选项]同上,但使用
    Firestore.Decoder
    解析结果
    ChatModelFirebase
  • [解析逻辑很危险]在云函数上执行查询,返回JSON,然后手动将结果解析为
    ChatModelFirebase
  • [代价太高]通过
    whereField(..)
    更新所有查询的我的firestore文档结构,但这很复杂,因为
    whereField
    的选项有限

  • 我还缺什么?有更好的方法吗?

    如果您最终保留了当前的逻辑(在客户机上进行过滤),以下是一些技巧,您可以进一步限制文档

  • 您不能在查询中使用
    declinedParticipants
    ,因为查询只能询问“哪些文档具有此值”,而不能询问“哪些文档没有此值”。您可以维护并使用
    notDeclinedParticipants
    字段:
  • 由于
    numParticipants
    包含不同的小整数,因此可以使用:
  • 要添加基于
    eventTime
    的范围筛选器并运行,请创建一个复合索引,该索引将包括需要放入查询中的所有其他字段,以及
    eventTime
  • 示例(未测试)代码:


    如果说#3是指更新存储的数据以简化查询,那么我认为您已经涵盖了所有主要选项。是的,没错。您会推荐哪一种树选项?我的选择可能是#1。没有一种单一的方法最适合所有情况和所有人。我个人更喜欢从不从云函数进行客户端读取,所以我不使用#2。但这是个人偏好/权衡,因为我总是试图展示实时更新/听众的力量。我对#3很有好感,但我总是纠结于是从客户端进行复制/扇出,还是在云端执行。
    .whereField("notDeclinedParticipants", arrayContains: me)
    
    .whereField("numParticipants", in: [1, 2, 3, 4, 5])
    
    Firestore.firestore().collection("chats")
        .whereField("notDeclinedParticipants", arrayContains: me)
        .whereField("numParticipants", in: [2, 3, 4, 5])
        .whereField("isDebug", isEqualTo: DebugGating.isDebugBuild())
        .whereField("eventTime", isGreaterThan: earliestEventTime)