Как подписаться на подписку в сообщениях Flutter Firebase?

# #firebase #flutter #dart #firebase-cloud-messaging

Вопрос:

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

Позвольте мне прояснить ситуацию более четко. В моем приложении есть несколько пользователей, и мне удалось настроить вложенные коллекции для обмена сообщениями. Таким образом, для каждого пользователя существует коллекция /пользователи и вложенная коллекция сообщений. Я хочу подписаться на подсекцию /сообщения, чтобы получать изменения с помощью функций Firebase.

Код для функций Firebase в Typescript выглядит следующим образом:

 functions.firestore.
    document("users/{userId}/messages/{messageId}")
    .onCreate((snapshot, context) => {
      console.log(snapshot.data());
      console.log(snapshot.data());

      return admin.messaging().sendToTopic("users", {
        notification: {
          title: snapshot.data()["username"],
          body: snapshot.data()["text"],
          clickAction: "FLUTTER_NOTIFICATION_CLICK",
        },
      });
    });
 

Однако я не знаю, как подписаться на подколлекцию в стороне Flutter (чтобы подписаться на коллекцию, которую мы используем FirebaseMessaging.instance.subscribeToTopic('users'); ).

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

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

1. В Firebase Cloud Messaging нет понятия коллекций или вложенных коллекций, все, что у него есть, — это плоский список тем. Это очень похоже на проблему XY . Чего вы пытаетесь достичь с помощью этой облачной функции (не реализации, а варианта использования)?

2. Я хочу подписаться на пользователей в /users/{идентификатор пользователя}/коллекцию сообщений, где в Firestore сообщения называются подколлекцией коллекции пользователей. Я хочу подписаться на сообщения одного пользователя и из облачных функций я хочу отправлять уведомления пользователю, когда он подписывается на /users/{Идентификатор пользователя}/коллекция сообщений. Надеюсь, я все правильно объяснил.

Ответ №1:

В Firebase Cloud Messaging нет понятия коллекций или вложенных коллекций, все, что у него есть, — это плоский список тем.

Таким образом, вам придется придумать собственное сопоставление вложенных коллекций с уникальными именами тем, например, используя оба идентификатора документов: users_<userId>_messages_<messageId> . С такой структурой вы, пользователи, можете подписаться на эту конкретную тему, и ваш код на стороне сервера может отправлять в ту же тему что-то вроде:

 functions.firestore.
    document("users/{userId}/messages/{messageId}")
    .onCreate((snapshot, context) => {
      console.log(snapshot.data());
      console.log(snapshot.data());

      return admin.messaging().sendToTopic(
        `users_${context.params.userId}_messages_${context.params.messageId}`, {
        notification: {
          title: snapshot.data()["username"],
          body: snapshot.data()["text"],
          clickAction: "FLUTTER_NOTIFICATION_CLICK",
        },
      });
    });
 

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

1. Спасибо за ответ. Теперь это имеет смысл. В Flutter я должен использовать коллекцию для подписки, а не документ, верно? Я имею в виду, что вы написали users_<Идентификатор пользователя>_messages_<Идентификатор пользователя><Идентификатор сообщения>, но это должны быть users_<Идентификатор сообщения><Идентификатор пользователя>_messages, чтобы подписаться на стороне Flutter.

2. Я не совсем понял ваш вариант использования, поэтому скопировал довольно буквально то, что говорится в вашем вопросе, в тему. Но если вы хотите «просто» нацелить каждого пользователя на тему, вы можете использовать только users_${context.params.userId} часть в теме. Обратите внимание, что темы не являются частными, поэтому с помощью этой схемы вы можете подписаться на чьи-либо сообщения, если вам известен их UID, что может быть нормально или нет в вашем случае использования.

3. Это может иметь смысл, но как насчет document("users/{userId}/messages/{messageId}") того , чтобы, не зная идентификатор пользователя здесь, можно ли обнаружить вложенную коллекцию сообщений?

4. Да, объявление облачных функций, которое у вас есть, прослушивает все messages вложенные коллекции всех пользователей.

5. Эй, @FlutterDev, здесь еще что-нибудь нужно?