Запросить хранилище огня, чтобы получить все токены от идентификатора пользователя

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

const aNotify = [{id: 'id001', text: 'specialTextFor001'}, {id: 'id002', text: 'specialTextFor002'};

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

devices

Можно ли сделать это через БД, например, с предложением where, или мне нужно сделать это, получив все устройства и в облачном методе выполнить foreach ...?

Функция получать() CollectionReference возвращает обещание, которое будет разрешено с результатами запроса. Соберите все обещания в список и передайте это функции all () для ответа, когда весь набор будет завершен, как объяснено здесь, верно?

Alex Mamo 31.10.2018 13:33

@AlexMamo, вы имеете в виду создать список обещаний для каждого предложения where в userId? разве это не будет излишним?

MichaelAngelo 31.10.2018 14:30

да. Не будет. См. Ответ Дуга из этого Почта. Предназначен для Android, но вы можете добиться того же и для Интернета.

Alex Mamo 31.10.2018 14:39
0
3
525
1

Ответы 1

Чтобы найти документ device, соответствующий userId, вы должны использовать простой запрос, например:

const db = admin.firestore();
db.collection('devices').where("userId", "==", element.id).get();

см. соответствующий документ здесь.

Поскольку вам нужно сделать запрос для каждого элемента массива aNotify, вам необходимо использовать Promise.all(), поскольку get() возвращает обещание.

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

    const db = admin.firestore();

    var aNotify = [{ id: 'id001', text: 'specialTextFor001' }, { id: 'id002', text: 'specialTextFor002' }];

    var promises = []
    aNotify.forEach(function (element) {
        promises.push(db.collection('devices').where("userId", "==", element.id).get());
    });
    return Promise.all(promises)   
        .then(results => {
            results.forEach(querySnapshot => {
                querySnapshot.forEach(function (doc) {
                    console.log(doc.id, " => ", doc.data());
                    //here, either send a notification for each user of populate an array, or....
                    //e.g. return admin.messaging().sendToDevice(doc.data().token, ....);
                });
            });
        });

Обратите внимание, что массив results имеет точно такой же порядок, что и массив promises. Так что получить свойство text соответствующего объекта массива aNotify при отправке уведомлений несложно.

Спасибо за помощь, но при этом будут использоваться сетевые вызовы, верно? Я имею в виду эту часть promises.push (db.collection ('devices'). Where ("userId", "==", element.id) .get ());

MichaelAngelo 31.10.2018 22:32

@MichaelAngelo Он будет запрашивать один документ по userId (при условии, что userId связан только с одним устройством). С вашей моделью данных нет другого пути ... или вы денормализуете свои данные и помещаете что-нибудь в один документ, например в массиве. Но тогда вам придется позаботиться об ограничениях Firestore, см. firebase.google.com/docs/firestore/quotas#limits

Renaud Tarnec 01.11.2018 08:24

Другие вопросы по теме