Как отфильтровать подколлекцию в firebase (flutter)?

# #firebase #flutter #google-cloud-firestore

Вопрос:

У меня есть коллекция под названием Channels , и внутри нее у меня есть подколлекция под названием messages , поэтому я хочу отфильтровать коллекцию каналов, а затем я хочу извлечь из нее сообщения ?

 FirebaseFirestore.instance
        .collection('Channels') >> where(id = user.uid) <<<<< I want to filter this 
        .doc()
        .collection("messages")
        .orderBy("createdAt")
        .snapshots(),
 

Огневая база

*любая помощь будет признательна ^^

ошибка : сообщение об ошибке

Метод «doc» не определен для типа «Запрос». Попробуйте исправить имя на имя существующего метода или определить метод с именем «doc».

Ответ №1:

Согласно этой ссылке, вы должны использовать where метод. Объедините это с документами firebase.flutter.dev (заголовок с соответствующим примером здесь), вы сможете сделать это, используя что-то вроде:

 FirebaseFirestore.instance
  .collection('Channels')
  .where('id', isEqualTo: user.uid)
 

Также совпадает ли идентификатор канала с идентификатором отправителя? Если ответ «да», нужны ли вам и то, и другое (и уверены ли вы, что это та структура, которая вам нужна)? 🙂

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

1. Да, но все равно я не могу поставить условие» где » следующим образом : FirebaseFirestore.instance .collection («Каналы»). где ( «). doc() >>>>>> ошибка : метод » doc «не определен для типа «Запрос». Попробуйте исправить имя на имя существующего метода или определить метод с именем «doc». .коллекция(«сообщения») .Порядок(«Созданный») . снимки(),

2. FirebaseFirestore.instance.collection('Channels').where('id', isEqualTo: user.uid).doc().collection("messages") возвращает ли какая-либо ошибка?

3. Я обновил сообщение, вы можете видеть, что я имею в виду ^^

Ответ №2:

Запрос Firestore может получить доступ только к документам из одной коллекции или из группы коллекций с одинаковыми именами. Таким образом, вы не можете фильтровать документы на messages основе полей в их родительском Channels документе.

Что вы можете сделать, так это добавить соответствующее поле в каждый messages документ, например, в поле с именем channelUID . Затем вы можете использовать запрос группы коллекций для запроса всех messages коллекций:

 FirebaseFirestore.instance
        .collectionGroup("messages")
        .orderBy("createdAt")
        .where("channelUID", isEqualTo: user.uid)
        .snapshots(),
 

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

1. проблема в том, что пользователь может создать более одного канала, каждый канал имеет уникальный идентификатор получателя . если я использую вашу функцию для запроса всех сообщений, она будет извлекать все сообщения со всех каналов.вот функция, которую я использовал для отправки сообщения ` void onSend(сообщение ChatMessage) { FirebaseFirestore .instance .collection(‘Каналы’). doc (). коллекция(«сообщения»). doc(Дата и время.сейчас (). Миллисекунды). Точка. строка ()). набор(сообщение. toJSON()); setState (() { сообщения = […сообщения, сообщение]; печать(сообщения. длина); });`

2. .where("channelUID", isEqualTo: user.uid) Фильтры на UID, такие же, как и в запросе в вашем вопросе. Единственное отличие состоит в том, что теперь вам нужно добавить это поле в каждый документ во messages вложенных коллекциях, чтобы разрешить вариант использования. Если вы все еще получаете слишком много результирующих документов, вам придется добавить messages в документы дополнительные поля, чтобы разрешить их фильтрацию, поскольку Firestore может получать доступ к документам только из одной коллекции в запросе или из группы коллекций с одинаковыми именами.

3. У OP есть своя структура данных. Таким образом, изменение структуры базы данных-это не то, о чем просят. Ваш ответ не ошибочен, если бы вопрос заключался в том, как его можно было бы реструктурировать

Ответ №3:

Проблема в том, что doc() он пуст, поэтому FB не знает, в какой документ войти.

Просто добавьте идентификатор канала внутри doc() , вот так:

 FirebaseFirestore.instance
  .collection('Channels')
  .doc(recieverID)
  .collection('messages')
  .orderBy('createdAt')
 

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

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

2. понял. Обновление ответа сейчас