Преодоление небольшой задержки обновления firestore

#android #firebase #google-cloud-firestore

#Android #firebase #google-облако-firestore

Вопрос:

Что я пытаюсь сделать, так это то, что
я получаю клики от пользователей на разных клиентах,
и мне нужно знать, на каком из них нажали первым.

У меня есть документ, в который записываются клиенты,
и моя идея заключалась в том, чтобы позволить клиентам изменять его, если это пустая строка.
В противном случае, если он уже заполнен (с идентификатором пользователя), вы не сможете применить изменение.
Таким образом, я смогу узнать, какой пользователь нажал первым.

Проблема с этим решением заключается в том, что оно работает на стороне клиента,
и возникает небольшая задержка, из-за которой пользователям, которые не нажали первыми,
приходится обновлять свой идентификатор пользователя, потому что, когда они нажимали, реальный первый пользователь еще не был обновлен.

Итак, я новичок в firestore и firebase, и мой вопрос таков:
есть ли способ преодолеть эту проблему?

У меня была другая идея, по сути, позволить всем клиентам отправлять текущее время в firestore,
а затем проверять, кто первый, но мне интересно, есть ли способ реализовать мою первую идею и заставить ее работать.

спасибо!

Ответ №1:

Я думаю, вы могли бы извлечь выгоду из атомарности транзакций (https://firebase.google.com/docs/firestore/manage-data/transactions )

Транзакция будет выглядеть следующим образом:

  • прочитайте поле string
  • если оно пустое, напишите и верните «первое по успешности», если это не так, верните «кто-то уже там»
  • Если кто-то уже выполняет транзакцию в этом поле, повторяйте транзакцию до тех пор, пока другая транзакция не будет завершена (firestore автоматически сделает это за вас)

Комментарии:

1. Если я правильно понимаю: пользователь может перезаписать firstToClick строку, если он нажмет, когда другой пользователь уже нажал? И вписать его идентификатор в firstToClick поле вместо другого пользователя (который на самом деле был первым)? Если это так, атомарность транзакции не позволила бы этого, потому что вы бы систематически читали из базы данных перед ее изменением, проверяя наличие пустой строки. Если вам удастся написать на нем, вы можете быть уверены, что будете единственным пользователем, пишущим на нем с описанной выше реализацией. Если они оба вводят транзакцию перед ее отправкой, только один из двух пользователей завершит ее.

2. Да, точно. Итак, в основном; пользователь1 щелкает, проверяет, что строка пуста (так и есть), его идентификатор обновляется в поле; Между тем, пользователь2 щелкает сразу после того, как это сделал пользователь1, проверяет, что строка пуста ( это так, поскольку идентификатор пользователя 1 еще не был обновлен), его идентификатор обновляется в поле.

3. Из документа: «Например, если транзакция считывает документы, а другой клиент изменяет какой-либо из этих документов, Cloud Firestore повторяет транзакцию». Так что да, этого не произойдет. Последний пользователь получит повторную транзакцию и, наконец, вернет «в строке что-то есть, я не могу в нее записать»

4. Хорошо, теперь это интересно, я собираюсь попробовать это и рассказать вам, как это сработало, спасибо!

5. Из того, что я пробовал прямо сейчас, кажется, это работает. Потрясающе, спасибо!

Ответ №2:

Я бы выбрал проверку даты, но делать это на стороне клиента было бы не очень безопасно, потому что различия в местном времени могут привести к неправильной идентификации пользователей как ранних или поздних. Для решения этой проблемы я вижу два варианта:

  1. Первым было бы создание облачной функции HTTPS, где вы могли бы получить дату сервера и отправить ее в базу данных. Таким образом, на вас не влияет локальная дата на устройствах ваших пользователей. Вы также могли бы сделать то же самое, разместив этот код в любом месте, где захотите, и вызвав его с помощью HTTP, функция Cloud просто проще.

  2. Другим вариантом было бы сначала сохранить дату и пользователя в базе данных реального времени. Он был создан для приложений реального времени, поэтому, вероятно, его написание будет быстрее, чем в Firestore. Затем вы можете создать функцию DB Cloud, которая получит дату и отправит ее в Firestore, и там вы сможете проверить, какой пользователь сохранил файл первым.