Я хочу синхронизировать контакты пользователей с firebase firestore за один раз

Я создаю приложение для чата, похожее на WhatsApp. Я хочу показать список зарегистрированных пользователей приложения из списка контактов устройства пользователя при создании новой группы. Теперь, чтобы сделать это, мне нужно сравнить каждый контактный номер с пользователями firebase firestore. А у любого обычного пользователя в устройстве может быть более 500 контактов. И, кроме того, у firestore есть ограничение на запросы к базе данных, поэтому я не могу сравнивать более одного числа за раз, весь процесс занимает почти 6-7 минут, а каждая операция чтения требует финансовых затрат.

Как я могу справиться с этой ситуацией или как лучше справиться с этим конкретным сценарием?


person Sagar Khatri    schedule 27.08.2018    source источник
comment
Я только что протестировал это с помощью быстрого приложения Firebase (не Firestore), и я могу запросить 500 телефонных номеров примерно за 2 секунды (Swift 4) и сохранить соответствующие в массиве. Не уверен, что вызывает задержку, но это не Firestore, так как производительность недалеко от Firebase.   -  person Jay    schedule 27.08.2018
comment
При дальнейшем тестировании предполагается, что вы найдете соответствие для каждого контакта (500 из них), что увеличивает время до 8 секунд, включая печать на консоли. Теперь это с помощью запроса. Если вы создаете узел, который хранит только номера телефонов, вы можете полностью избежать запроса и просто проверить, существует ли узел. В таком случае он настолько быстр, что даже не стоит его измерять.   -  person Jay    schedule 27.08.2018
comment
@Jay Я не знаю, как расходуется время с БД в реальном времени, но я использую react native и firestore, чтобы наверняка потратить столько времени.   -  person Sagar Khatri    schedule 28.08.2018
comment
@Jay ok Я также пробовал с БД в реальном времени, и он снизился до 4 минут, но у вас 4 секунды .. Могу ли я получить вашу структуру БД и быстрый код, как вы делаете запрос.   -  person Sagar Khatri    schedule 28.08.2018
comment
@Jay, пожалуйста, поделитесь схемой?   -  person Sagar Khatri    schedule 29.08.2018
comment
@SagarKhatri, можешь поделиться своим окончательным решением?   -  person epic    schedule 25.01.2020
comment
@Ran мы отказались от всей функции синхронизации. Я думаю, вам нужен сервер для выполнения такого процесса. В противном случае будет много операций чтения / записи / обновления, и вы в конечном итоге заплатите гораздо больше firebase.   -  person Sagar Khatri    schedule 27.01.2020


Ответы (2)


Вы можете хранить контакты пользователя на устройстве и отправлять их в firestore только в качестве резервной копии. Затем вы можете синхронизировать локальную базу данных с хранилищем огня при запуске приложения. Необходимые вам операции не могут быть надежными в firebase. Даже в этом случае, если вы хотите выполнить поиск в данных firebase, вам необходимо использовать стороннее поисковое решение, такое как Elastic Search, с вашими данными firebase для выполнения сложного поиска.

Для локальной базы данных вы можете использовать библиотеку Room: https://developer.android.com/topic/libraries/architecture/room

Для использования эластичного поиска с Firebase взгляните на эту утилиту Flashlight: https://github.com/FirebaseExtended/flashlight < / а>.

person Umar Hussain    schedule 27.08.2018
comment
Мне не нужен ни сложный поиск, ни даже текстовый поиск. это точное сравнение текста, например device.phoneNumber == firestore.phoneNumber но дело в том, что у меня более 500 контактов, и это требует времени, и я синхронизирую контакты при запуске приложения, но что, если пользователь просто закроет приложение через минуту или около того. сейчас синхронизация занимает более 6 минут - person Sagar Khatri; 27.08.2018
comment
вы можете сделать синхронизацию эффективной, используя дочерний прослушиватель событий и продолжая хранить данные в локальной базе данных, в следующий раз, когда приложение запустится, получите последнюю локально сохраненную запись, получите ее идентификатор, чтобы ваш запрос читался с этой точки. это будет работать, поскольку идентификаторы, сгенерированные firebase, отсортированы, поэтому вы не пропустите ни одного. - person Umar Hussain; 27.08.2018
comment
это может помочь мне в синхронизации, но я хочу оптимизировать это и хочу выполнить эту операцию за секунды .. - person Sagar Khatri; 27.08.2018
comment
проиндексируйте свои данные в локальной базе данных по телефонным номерам, и ваш поиск значительно ускорится. Также, если вы проиндексируете базу данных firebase и запросите напрямую, это также улучшит ваш поиск в firebase. - person Umar Hussain; 27.08.2018
comment
firestore автоматически индексирует ваш ключ документа, поэтому это не проблема, и я сохраняю контакты устройства в своем приложении, так что это тоже не проблема. - person Sagar Khatri; 27.08.2018

OP запросил структуру и некоторый код (Swift, Firebase Database) в качестве решения. Я представлю два варианта

Если вы хотите использовать запрос 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.

ИМО, лучший и значительно более быстрый вариант - сохранить узел только с телефонными номерами. Затем переберите те, которые вы ищете, и используйте .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)")
        }
    })
}

При тестировании это второе решение должно быть быстрее, чем первое.

person Jay    schedule 29.08.2018