Как запросить более одного элемента в массиве в Firestore? ( «Массив содержит») - PullRequest
0 голосов
/ 24 августа 2018

Я создаю чат-приложение 1-к-1 с Firestore и Javascript (vue.js).

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

.collection ( "coversation"). Док ()

conversation: {
  participantsArray: ["id1", "id2"],
  participants: {
    id1: {
      /* details like avatar & name */
    },
    id2: {
      /* details like avatar & name */
    }
  }
}

.collection ( "coversation"). Документ ( "Foo"). Коллекция ( "сообщения"). Док ()

message: {
  message: "foo"
}

Это здорово, поэтому теперь я могу запрашивать все разговоры определенного пользователя, например:

db.collection('conversations').where("participantsArray", "array-contains", userId)

У меня возникла следующая проблема:

Я хочу запросить конкретную беседу, вот так:

db.collection('conversations')
  .where("participantsArray", "array-contains", userId)
  .where("participantsArray", "array-contains", chatpartnerId)

Но это не работает, поскольку двойное "array-contains" не разрешено и выдает сообщение об ошибке.

Сейчас у меня работает два звонка:

db.collection('conversations')
  .where(`participantsArray`, '==', [userId, chatpartnerId])

db.collection('conversations')
  .where(`participantsArray`, '==', [chatpartnerId, userId])

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

Это работает, но это куча кода и довольно неэффективно.

Так что мой вопрос будет:

  1. Есть ли лучший способ сделать это?
  2. Как сделать "массив-содержимое", чтобы проверить наличие нескольких элементов?
  3. У меня есть и поле membersArray , и поле members , потому что я не понял, как сделать "array-contains" в массиве объектов. Есть ли способ или я должен оставить оба поля?

PS: Раньше я делал запросы к объектам в объекте участников так:

db.collection("conversations").where(`participants.${userId}.id`, "==", userId)

Это был предложенный способ запроса до появления «массива-содержимого», но в сочетании с orderBy мне пришлось бы создавать индекс для каждого пользователя, что на самом деле не вариант.

Ответы [ 2 ]

0 голосов
/ 09 января 2019

Альтернативой является наличие в документе двух полей: одного для наименьшего алфавитного идентификатора пользователя (LAUID) и одного для наивысшего алфавитного идентификатора пользователя (HAUID). Если у вас есть оба идентификатора пользователя на клиенте, но вы не знаете, какой из них какой, вы можете выяснить, какой идентификатор больше из двух (UID2), а какой - наименьший (UID1), тогда ваш запрос будет там, где HAUID равен UID2 и где LAUID равен UID1

0 голосов
/ 24 августа 2018

Я нашел способ, как запросить один разговор.

Поскольку у меня есть оба (1) участника с деталями в объекте " members " и (2) идентификаторы участника в " membersArray ", я могу запросить одиночный разговор следующим образом:

db.collection('conversations')
      .where(`participants.${userId}.id`, "==", userId)
      .where(`participants.${chatPartnerId}.id`, "==", chatPartnerId)

Так что я счастлив сейчас. Тем не менее, эти три вопроса остаются, поэтому, если кто-то сможет ответить на них правильно, их ответ будет очень ценным:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...