В облачной функции, как я могу присоединиться из другой коллекции, чтобы получить данные? - PullRequest
0 голосов
/ 24 января 2019

Я использую облачную функцию для отправки уведомления на мобильное устройство. У меня есть две коллекции в Firestore clientDetail и clientPersonalDetail. У меня clientID одинаково в обеих коллекциях, но дата хранится в clientDetail, а имя хранится в clientPersonal.

Взгляните:

ClientDetail -- startDate
             -- clientID
             .......

ClientPersonalDetail -- name
                     -- clientID
                     .........

Вот мой полный код:

exports.sendDailyNotifications = functions.https.onRequest(  (request, response) => {
var getApplicants = getApplicantList();
console.log('getApplicants', getApplicants);

cors(request, response, () => {
  admin
    .firestore()
    .collection("clientDetails")
    //.where("clientID", "==", "wOqkjYYz3t7qQzHJ1kgu")
    .get()
    .then(querySnapshot => {
      const promises = [];
      querySnapshot.forEach(doc => {
        let clientObject = {};
        clientObject.clientID = doc.data().clientID;
        clientObject.monthlyInstallment = doc.data().monthlyInstallment;
        promises.push(clientObject);
      });

      return Promise.all(promises);
    }) //below code for notification
    .then(results => {
      response.send(results);
      results.forEach(user => {
        //sendNotification(user);
      });
      return "";
    })
    .catch(error => {
      console.log(error);
      response.status(500).send(error);
    });
});

} );

Выше функции показывает объект, подобный этому

{clienId:xxxxxxxxx, startDate:23/1/2019}

Но мне нужно, чтобы ClientID, а не имя отображалось в уведомлении, поэтому мне придется присоединиться к коллекции clientPersonal, чтобы получить имя с помощью clientID. Что делать?

Как я могу создать другую функцию, которая исключительно возвращает имя, передавая clientID в качестве аргумента, и ждет, пока она не вернет имя. Кто-нибудь, пожалуйста, помогите .?

Ответы [ 3 ]

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

«Более простым» решением, вероятно, было бы дублирование данных.Это довольно часто встречается в мире NoSQL.

Точнее, вы добавили бы в свои документы в коллекцию ClientDetail значение клиента name.

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

В этом случае вы можете использовать две дополнительные функции для очистки кода. Одна функция, которая будет читать все документы из коллекции ClientDetail и вместо того, чтобы получать все поля, получит только ClientID. Затем вызовите другую функцию, которая будет сканировать все документы в коллекции ClientPersonalDetail и получить только часть с ClientID. Сравните, совпадают ли эти два, а затем выполните какие-либо операции, если они это сделают.

Вы можете обратиться к Начало работы с Cloud Firestore Документация о том, как создавать, добавлять и загружать документы из Firestore.

Ваш package,json должен выглядеть примерно так:

{
  "name": "sample-http",
  "version": "0.0.1",
  "dependencies": {
    "firebase-admin": "^6.5.1"
  }
}

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

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

Но мне нужно, чтобы ClientID, а не имя отображалось в уведомлении, поэтому мне придется присоединиться к коллекции clientPersonal, чтобы получить имя с помощью clientID.Что делать?

К сожалению, в Firestore нет предложения JOIN.Запросы в Firestore мелкие.Это означает, что они получают только элементы из коллекции, к которой выполняется запрос.Нет возможности получить документы из двух коллекций верхнего уровня за один запрос.Firestore не поддерживает запросы к различным коллекциям за один раз.В одном запросе могут использоваться только свойства документов в одной коллекции.

Как создать другую функцию, которая возвращает только имя, передавая clientID в качестве аргумента, и ожидает, пока не вернется имя.

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

Другим решением было бы добавить имя пользователя в качестве нового свойства в ClientDetail, чтобыВы можете запросить базу данных только один раз.Эта практика называется denormalization и является обычной практикой, когда дело доходит до Firebase.Если вы новичок в базах данных NoQSL, я рекомендую вам посмотреть это видео, Денормализация нормальна с базой данных Firebase для лучшего понимания.Это для базы данных реального времени Firebase, но те же правила применяются к Cloud Firestore.

Кроме того, когда вы дублируете данные, есть одна вещь, которую нужно иметь в виду.Точно так же, как вы добавляете данные, вы должны поддерживать их.Другими словами, если вы хотите обновить / обнаружить элемент, вы должны делать это в каждом месте, где он существует.

...