如何使用另一个用户插入的电子邮件发送通知,该用户使用 Cloud Functions for Firebase 请求通知?

How can I send a notification by using the email inserted by another user who requested the notification using Cloud Functions for Firebase?

我是 Cloud Functions for Firebase 的初学者,我正在开发一个 Web 应用程序,使用它向特定用户发送通知。但是,问题是我想让用户决定他想向谁发送消息,而我发现这样做的方法是允许用户通过我网站中的表单插入接收者的电子邮件,所以我可以将它保存在我的数据库中,然后激活一个功能,该功能会向注册用户发送先前创建的通知,该注册用户具有发件人用户插入的相同电子邮件。

所以,我知道每当用户发送带有接收者电子邮件的表单时我都必须触发该函数,因为这是我的数据库发生更改的时候。但是,我不知道如何将插入的电子邮件与所有其他用户的电子邮件进行比较,然后只捕获正确用户的令牌来发送通知。有人知道怎么做吗?

这些是我的代码,我以 的某些部分作为基础,JSON 来自我的数据库的一部分:

函数

const functions = require('firebase-functions');

const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.sendPush = 
functions.database.ref('/Messages/Receivers/{pushId}').onWrite(event => {

const snapshot = event.data;

const email = snapshot.val().email;
const getAllUsersPromise = admin.database().ref('Users/').once('value');

const payload = {

    notification: {
        title: 'You have a notification',
        body: 'You received a new message'
    }

};

return getAllUsersPromise.then(result => {
    const userUidSnapShot = result;

    const users = Object.keys(userUidSnapShot.val());

    var AllUsersFCMPromises = []; 
    for (var i = 0;i<userUidSnapShot.numChildren(); i++) {
        const user=users[i];
        console.log('getting promise of user uid=',user);
        AllUsersFCMPromises[i]= admin.database().ref(`/Users/${user}/email`).equalTo(email).once('value').then(token => {
            var token = admin.database().ref(`/Users/${user}/token`).once('value');
            return token; 
        });
    }

    return Promise.all(AllUsersFCMPromises).then(results => {

        var tokens = []; 
        for(var i in results){
            var usersTokenSnapShot=results[i];
            console.log('For user = ',i);
            if(usersTokenSnapShot.exists()){
                if (usersTokenSnapShot.hasChildren()) { 
                    const t=  Object.keys(usersTokenSnapShot.val()); 
                    tokens = tokens.concat(t); 
                    console.log('token[s] of user = ',t);
                }
                else{

                }
            }
        }
        console.log('final tokens = ',tokens," notification= ",payload);
        return admin.messaging().sendToDevice(tokens, payload).then(response => {

            const tokensToRemove = [];
            response.results.forEach((result, index) => {
                const error = result.error;
                if (error) {
                    console.error('Failure sending notification to uid=', tokens[index], error);

                    if (error.code === 'messaging/invalid-registration-token' || error.code === 'messaging/registration-token-not-registered') {
                        tokensToRemove.push(usersTokenSnapShot.ref.child(tokens[index]).remove());
                    }
                }
                else{
                    console.log("notification sent",result);
                }
            });
        });
    }); 
});
});

JSON结构

    {  
  "Messages" : {
    "Receivers" : {
      "-Ko-Gc8Ch58uYKGIT_Ze" : {
        "email" : "phgrespan@gmail.com"
      },
    }
  },

  "Users" : {
    "1rwdq0O9Iqdo1JUNauwmlC9HXfY2" : {
      "apartamento" : "12",
      "bloco" : "L",
      "celular" : "148162491784",
      "email" : "jose@gmail.com",
      "nome" : "josé",
      "sobrenome" : "josé",
      "telefone" : "418947912497",
      "token" : "een1HZ0ZzP0:APA91bHaY06dT68W3jtlC3xykcnnC7nS3zaNiKBYOayBq-wuZsbv1DMFL8zE6oghieYkvvSn39bDCkXLtc3pfC82AGd8-uvmkuXCkPoTuzxMk14wVQNOB01AQ6L7bmsQBisycm2-znz7"
    }, 
    "CZv1oxUkfsVpbXNBMQsUZNzSvbt1" : {
      "apartamento" : "8",
      "bloco" : "P",
      "celular" : "123456789",
      "email" : "phgrespan@gmail.com",
      "nome" : "Pedro",
      "sobrenome" : "Henrique",
      "telefone" : "99876543234",
      "token" : "dvE4gBh1fwU:APA91bF9zLC1cOxT4jLsfPRdsxE8q0Z9P4uKuZlp8M5fIoxWd2MOS30u4TLuOQ4G2Sg0mlDqFMuzvjX3_ZSSi9XATyGtTtNse4AxwLYuD-Piw9oFn6Ma68nGfPSTnIEpvDYRwVnRI2e4"
    },
  }
}

我希望从那时起我能够让自己被理解和感谢。

当您只需要查询拥有所选电子邮件的一个或多个用户时,您似乎在查询所有用户。不要使用 getAllUsersPromise,而是使用 .orderByChild() 并查询电子邮件等于所选电子邮件的 children。

let selectedUsers = admin.database.ref('Users/').orderByChild('email').equalTo(email).once(snap => {
    // Get the token
})

这将为您提供拥有该电子邮件的一个或多个用户的快照。然后您可以遍历快照并获取令牌。