Firebase Cloud Function error: некоторые значения отображаются как неопределенные? - PullRequest
1 голос
/ 14 мая 2019

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

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

   'use strict';

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

    admin.initializeApp({
       credential: admin.credential.applicationDefault(),
       databaseURL: 'https://[MY DATABASE URL]/'
    });

     const gmailEmail = functions.config().gmail.email;
     const gmailPassword = functions.config().gmail.password;
     const mailTransport = nodemailer.createTransport({
        service: 'gmail',
        auth: {
           user: gmailEmail,
           pass: gmailPassword,
         },
       });       

         var email;
         var exitTime;
         var name;
         var userScore;

 exports.gameDoneNotice=functions.database.ref("USERS/{termDate}/GameData/{myUID}/ExitDateTime")
  .onCreate(async (snapshot, context) => {

         const myNumber = context.params.myUID; 
         const myRotation = context.params.termDate; 

            var adminDB = admin.database();

            exitTime = snapshot.val();

            var aRef = adminDB.ref("USERS/" + myRotation + "/GameData/" + myNumber + "/");
            aRef.on("value", (snapshot) => {
                email = snapshot.child("eMail").val();
                name = snapshot.child("Name").val();
                userScore = snapshot.child("User Score").val();
            });

            var emailsaad = "MYEMAIL@EMAIL.COM";

            console.log(myNumber);
            console.log(myRotation);
            console.log(userScore);
            console.log(name); 


        const APP_NAME = 'WCM-Q DeLib eLearning';        

        const mailOptions = {
             from: `${APP_NAME} <noreply@firebase.com>`,
             to: email,
             bcc: emailsaad,
            };  


         mailOptions.subject = `Welcome to ${APP_NAME}!`;
         mailOptions.html = `<h3>Dear, ${name}</h3><p>Thank you for completing the Medicine Clerkship EBM game.</p><hr><h4>Your Score: <font color="red">${userScore}</font></h4><h4>Game Completion  Time/Date: <font color="green">${exitTime}</font></h4><hr><p>If you have any questions about the game or your EBM project in this clerkship, don’t hesitate to ask for clarification. Otherwise, your next step is to begin to prepare with your group for your presentation.</p>`;


         try {
             await mailTransport.sendMail(mailOptions);
             console.log("eMail was a success");
           } catch(error) {
             console.error('Something has gone horribly wrong, bro!', error);
           }
            return null;

            });

Я ожидаю, что смогу прочитать значения, которые мне нужны для электронной почты, userScore и т. Д., Из базы данных и включить их в mailOptions перед его отправкой.Однако, когда я получаю электронное письмо после триггера, все значения из прочитанной базы данных «неопределены».

1 Ответ

0 голосов
/ 14 мая 2019

Вместо использования метода on(), который устанавливает прослушиватель «для изменений данных в определенном месте», необходимо использовать метод once(), который » прослушивает ровно одно событие указанного типа события ", а возвращает Обещание . После этого вы сможете использовать await, чтобы заставить облачную функцию ждать, пока обещание, возвращенное once(), не разрешится и не вернет свой результат.

Поэтому вы должны изменить свой код следующим образом:

exports.gameDoneNotice = functions.database
  .ref('USERS/{termDate}/GameData/{myUID}/ExitDateTime')
  .onCreate(async (snapshot, context) => {
    const myNumber = context.params.myUID;
    const myRotation = context.params.termDate;

    var adminDB = admin.database();

    exitTime = snapshot.val();

    var aRef = adminDB.ref(
      'USERS/' + myRotation + '/GameData/' + myNumber + '/'
    );

    try {
      const snapshot = await aRef.once('value');
      const email = snapshot.child('eMail').val();
      const name = snapshot.child('Name').val();
      const userScore = snapshot.child('User Score').val();

      const emailsaad = 'MYEMAIL@EMAIL.COM';

      console.log(myNumber);
      console.log(myRotation);
      console.log(userScore);
      console.log(name);

      const APP_NAME = 'WCM-Q DeLib eLearning';

      const mailOptions = {
        from: `${APP_NAME} <noreply@firebase.com>`,
        to: email,
        bcc: emailsaad
      };

      mailOptions.subject = `Welcome to ${APP_NAME}!`;
      mailOptions.html = `<h3>Dear, ${name}</h3><p>Thank you for completing the Medicine Clerkship EBM game.</p><hr><h4>Your Score: <font color="red">${userScore}</font></h4><h4>Game Completion  Time/Date: <font color="green">${exitTime}</font></h4><hr><p>If you have any questions about the game or your EBM project in this clerkship, don’t hesitate to ask for clarification. Otherwise, your next step is to begin to prepare with your group for your presentation.</p>`;

      await mailTransport.sendMail(mailOptions);
      //Here, actually you could also do return mailTransport.sendMail(mailOptions); , see the video mentioned below

    } catch (error) {
      console.error('Something has gone horribly wrong, bro!', error);
    }
  });

Вы можете посмотреть официальную серию Firebase Дуга Стивенсона, которая объясняет все эти моменты. В частности, 3 видео о «обещаниях JavaScript» и видео об async / await: https://www.youtube.com/watch?v=Jr7pDZ1RAUg

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...