首页 > 解决方案 > 我想一次性将用户联系人同步到 Firebase Firestore

问题描述

我正在构建聊天应用程序,有点像 whatsapp。我想在创建新组时从用户的设备联系人列表中显示注册的应用程序用户列表。现在为了做到这一点,我必须将每个联系人号码与 firebase firestore 用户进行比较。任何普通用户都可以在设备中拥有超过 500 个联系人。而且firestore对查询数据库有限制,所以我一次不能比较多个数字,整个过程几乎需要6-7分钟,而且每次读取操作都会产生经济成本。

我该如何克服这种情况,或者处理这种特殊情况的更好方法是什么?

标签: firebasegoogle-cloud-firestorechatquerying

解决方案


OP 要求提供一个结构和一些代码(Swift、Firebase 数据库)作为解决方案。我将介绍两个选项

如果您想使用 Firebase 查询来查看电话号码是否存在,可能的结构是

users
  uid_0
    contact_name: "Larry"
    contact_phone: "111-222-3333"
  uid_1
    contact_name: "Joe"
    contact_phone: "444-555-6666"

然后是查询现有号码的快速代码

let phoneNumbers = ["111-222-3333","444-555-6666"] //an array of numbers to look for
let myQueryRef = self.ref.child("users")
for contactPhone in phoneNumbers {
    let queryRef = myQueryRef.queryOrdered(byChild: "contact_phone").queryEqual(toValue: contactPhone)
    queryRef.observeSingleEvent(of: .childAdded, with: { snapshot in
        if snapshot.exists() {
            print("found \(contactPhone)") //or add to array etc
        }
    })
}

通常不建议在这样的紧密循环中进行查询,但它通常对我来说在迭代次数少的情况下效果很好。但是,查询比 .observers 有更多的开销。

IMO,一个更好且更快的选择是保留一个仅包含电话号码的节点。然后遍历您正在寻找的那些并使用 .observe 查看该节点是否存在。

phone_numbers
   111-222-3333: true
   444-555-6666: true

然后是查看数组中的那些是否存在的代码

let phoneNumbers = ["111-222-3333","444-555-6666"] //an array of numbers to look for
let phoneNumberRef = self.ref.child("phone_numbers")
for contactPhone in phoneNumbers {
    let ref = phoneNumberRef.child(contactPhone)
    ref.observeSingleEvent(of: .value, with: { snapshot in
        if snapshot.exists() {
            print("found \(contactPhone)")
        }
    })
}

在测试中,第二个解决方案必须比第一个解决方案更快。


推荐阅读