Javascript Firebase身份验证电子邮件问题-部署时出现Index.js错误

Javascript Firebase身份验证电子邮件问题-部署时出现Index.js错误,javascript,node.js,firebase,google-cloud-functions,nodemailer,Javascript,Node.js,Firebase,Google Cloud Functions,Nodemailer,从项目克隆的Index.js出现错误。这是一个Firebase项目,应该使用Firebase函数(NodeEmailer)发送一封验证电子邮件,其中包含一个用于验证所创建帐户的令牌。我的代码在顶部,错误如下: const functions = require('firebase-functions'); const admin = require('firebase-admin'); const nodemailer = require('nodemailer'); var cors = r

从项目克隆的Index.js出现错误。这是一个Firebase项目,应该使用Firebase函数(NodeEmailer)发送一封验证电子邮件,其中包含一个用于验证所创建帐户的令牌。我的代码在顶部,错误如下:

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

const nodemailer = require('nodemailer');
var cors = require('cors');
const secureCompare = require('secure-compare');

// Configure the email transport using the default SMTP transport and a GMail account.
// For other types of transports such as Sendgrid see https://nodemailer.com/transports/
// TODO: Configure the `gmail.email` and `gmail.password` Google Cloud environment variables.
const gmailEmail = encodeURIComponent(functions.config().gmail.email);
const gmailPassword = encodeURIComponent(functions.config().gmail.password);

const mailTransport = nodemailer.createTransport(
  `smtps://${gmailEmail}:${gmailPassword}@smtp.gmail.com`);

const APP_NAME = 'The Ride Share';

//admin.initializeApp(functions.config().firebase);
// var firebaseConfig = functions.config().firebase;
// firebaseConfig.databaseAuthVariableOverride = {
//   uid: 'fbcfunction',
// };

admin.initializeApp();


function sendWelcomeEmail(email, displayName, token) {
  const mailOptions = {
    from: 'The Ride Share',
    to: email
  };

  // The user unsubscribed to the newsletter.
  mailOptions.subject = `Welcome to ${APP_NAME}!`;
  mailOptions.text = `Hey ${displayName}!, Welcome to ${APP_NAME}. Your token is ${token}, Please enter the token in the portal to verify the account.`;
  return mailTransport.sendMail(mailOptions).then(() => {
    console.log('New welcome email sent to:', email);
  });
}

exports.prepareVerificationMail = functions.database.ref('/users/{uid}/shellMailId')
  .onWrite((change,context)=>{
    console.log('event', change);
    console.log('Mail id is', change.after.val());
    if (change.after.val() != null) {
      return change.after.parent.once('value').then(function (snapshot) {
        console.log('snapval is the user id', snapshot.key);
        var userId = snapshot.key;
        //console.log('this is the userId', userId);
        return userId;
      }).then(function (userId) {
        console.log('this should be user id', userId);

        return admin.database().ref().child('userTokens').child(userId).child('token').once('value')
          .then(function (token) {
            console.log('this is the token', token);
            var displayName = change.after.val().toString();
            if (displayName.indexOf('@') > -1) {
              displayName = displayName.substring(0, displayName.indexOf('@'));
            }
            console.log('displayName', displayName);
            return sendWelcomeEmail(change.after.val(), displayName, token.val());
          }).catch(function (error) {
            console.log('error in reading the user token', error);
            return;
          });

      }).catch(function (error) {
        console.log('error in getting user key', error);
        return;
      });
    } else {
      return;
    }
  });

exports.setTheToken = functions.database.ref('/users/{uid}/personalEmail')
  .onWrite((change,context)=>{

    console.log('event data val', change.after.val());
    console.log(change);
    if (change.after.val() != null) {
      //
      return change.after.parent.once('value').then(function (snapshot) {
        console.log('snapval is the user id', snapshot.key);
        var userId = snapshot.key;
        //console.log('this is the userId', userId);
        return userId;
      }).then(function (userId) {
        console.log('this should be user id', userId);  
        var token = parseInt(Math.random() * 100000);
        console.log('this is the token', token);
        return admin.database().ref().child('userTokens').child(userId).child('token').set(token).then(function (success) {

          console.log('success token set');
        }).catch(function (error) {
          console.log('Error token not set', error);
        });
      }).catch(function (error) {
        console.log('Error token not set', error);
      });
      //TOKEN PREVIOUSLY DOESNT EXIST THEN CREATE AND ASSIGN

    }
    else {
      console.log('personal email field value not present');
      return;
    }
  });


exports.removeActiveRequests = functions.https.onRequest((req, res) => {
  const key = req.query.key;

  // Exit if the keys don't match
  if (!secureCompare(key, functions.config().cron.key)) {
    console.log('The key provided in the request does not match the key set in the environment. Check that', key,
      'matches the cron.key attribute in `firebase env:get`');
    res.status(403).send('Security key does not match. Make sure your "key" URL query parameter matches the ' +
      'cron.key environment variable.');
    return;
  }

  console.log('delete all the active requests here');
  var userSeatsToUpdate = [];
  var firebaseRef = admin.database().ref().child('requests');

  return firebaseRef.once('value').then(function (snapshot) {
    snapshot.forEach(function (child) {
      if (userSeatsToUpdate.indexOf(child.val().requestedTo) < 0) {
        userSeatsToUpdate.push(child.val().requestedTo);
      }
    });
    return userSeatsToUpdate;
  }).then(function (success) {
    var promises = success.map(function (key) {
      return admin.database().ref().child('users').child(key).once("value");
    });

    return Promise.all(promises);
  }).then(function (snapshots) {
    var updates = {};
    snapshots.forEach(function (snapshot) {
      updates[snapshot.key + "/remainingSeats"] = snapshot.val().capacity;
    });
    return updates;

  }).then(function (listToUpdate) {
    var ref = admin.database().ref().child('users');
    return ref.update(listToUpdate);
  }).then(function (success) {
    console.log('success', success);
    //Add logic to move active requests to past requests, may for analytics    
    return firebaseRef.remove()    
  }).then(function(sucess) {
    console.log('active requests deleted', success);
    res.status(200).send('All requests are deleted');
  }).fcatch(function (error) {
    console.log('error:nightlyJob:', error);
    res.status(400).send('error', error);
  });

});



// CORS and Cloud Functions export logic
exports.verifyToken = functions.https.onRequest((req, res) => {
  var corsFn = cors();
  corsFn(req, res, function () {
    verifyTheUserToken(req, res);

  });
});


function verifyTheUserToken(req, res) {

  console.log('in verify token');
  if (req.method === 'PUT') {
    res.status(403).send('Forbidden!');
  }

  if (!req.headers.authorization || !req.headers.authorization.startsWith('Bearer ')) {
    console.error('No Firebase ID token was passed as a Bearer token in the Authorization header.',
      'Make sure you authorize your request by providing the following HTTP header:',
      'Authorization: Bearer <Firebase ID Token>');
    res.status(403).send('Unauthorized');
  }



  const firebaseToken = req.headers.authorization.split('Bearer ')[1];
  const userId = req.body.uid;
  const receievedToken = req.body.token;

  return admin.auth().verifyIdToken(firebaseToken).then(decodedFirebaseToken => {
    console.log('ID Token correctly decoded', decodedFirebaseToken);
    console.log('req', req.body);
    return 'sucess';

  }).then(function (receivedValues) {

    return admin.database().ref().child('userTokens').child(userId).child('token').once('value');

  }).then(function (snapshot) {

    console.log('this is the snap', snapshot);
    if (!snapshot.val()) {
      return Promise.reject('token is not set ');
    }

    console.log('snapshot.val(): ', snapshot.val(), 'receievedToken :', receievedToken);
    if (snapshot.val() != receievedToken) {
      return Promise.reject('token doesnt match');
    }

    return 'verified';

  }).then(function (sucess) {

    return admin.database().ref().child('users').child(userId).child('isVerified').set(true);

  }).then(function (sucess) {
    //DO A REDIRECT
    console.log('success in setting verified to true');
    res.send();
  }).catch(function (error) {
    //DECIDE WHAT YOU WANT TO DO
    console.log('Error', error);
    return admin.database().ref().child('users').child(userId).child('isVerified').set(true).then(function (success) {
      console.log('Setting verified to false');
      res.send();
    }).catch(function (error) {
      //DECIDE WHAT YOU WANT TO DO
      console.log('Error in setting false', error);
      res.send();
    });

  });

}


exports.handleRequestsForCarpooling = functions.database.ref('/requests/{uid}/')
  .onWrite((change,context)=>{

    console.log('new val', change.after.val());
    console.log('old val', change.before.previous.val());

    var rootRef = change.before.adminRef.root.child("users");

    if (change.after.val() !== null) {
      if (change.before.previous.val() !== null) {
        let firebaseRef = rootRef.child(change.before.previous.val().requestedTo).child('remainingSeats');

        firebaseRef.transaction(function (remainingSeats) {
          console.log('remainingSeats11111', remainingSeats);
          return remainingSeats + 1;
        }).then(function (success) {

          console.log('sucss', success);
        }).catch(function (error) {
          console.warn('error', error);
        });
      }
      let firebaseRef = rootRef.child(change.after.val().requestedTo).child('remainingSeats');
      firebaseRef.transaction(function (remainingSeats) {
        console.log('remainingSeats', remainingSeats);
        return remainingSeats - 1;
      }).then(function (success) {

        console.log('req', success);
      }).catch(function (error) {
        console.warn('error', error);
      });
    } else {
      console.log('no data');

    }

  });


exports.setRemainingSeatsOnCapacityChange = functions.database.ref('/users/{uid}/capacity')
  .onWrite((change,context)=>{

    if (change.before.previous.val() == change.after.val())
      return;

    var userId = '';

    if (change.before && change.after.val() != null) {
      return change.after.adminRef.parent.once('value').then(function (snapshot) {
        console.log('snapval is the user id', snapshot.key);
        userId = snapshot.key;
        console.log('userid', userId);
        return userId;
      }).then(function (userId) {
        return admin.database().ref().child('requests').orderByChild("requestedTo").equalTo(userId).once('value');

      }).then(function (snapshot) {

        if (snapshot.val())
          return Object.keys(snapshot.val()).length;
        else
          return 0;
      }).then(function (activeRequest) {
        var userRef = admin.database().ref().child("users").child(userId);
        console.log('this is the capacity', change.after.val());
        console.log('this is the activeRequest', activeRequest);
        var remainingSeats = change.after.val() - activeRequest;
        return userRef.update({
          remainingSeats: remainingSeats,
        });
      }).then(function (success) {
        console.log('success');
      }).catch(function (error) {
        console.error('error:', error);

      });
    }
  });
const functions=require('firebase-functions');
const admin=require('firebase-admin');
const nodemailer=require('nodemailer');
var cors=要求(“cors”);
const secureCompare=require('secure-compare');
//使用默认SMTP传输和GMail帐户配置电子邮件传输。
//有关其他类型的传输,如Sendgrid,请参阅https://nodemailer.com/transports/
//TODO:配置`gmail.email`和`gmail.password`谷歌云环境变量。
const gmailEmail=encodeURIComponent(functions.config().gmail.email);
const gmailPassword=encodeURIComponent(functions.config().gmail.password);
const mailTransport=nodemailer.createTransport(
`smtps://${gmailmail}:${gmailPassword}@smtp.gmail.com`);
const APP_NAME=‘骑乘共享’;
//admin.initializeApp(functions.config().firebase);
//var firebaseConfig=functions.config().firebase;
//firebaseConfig.databaseAuthVariableOverride={
//uid:'fbcfunction',
// };
admin.initializeApp();
函数sendWelcomeEmail(电子邮件、显示名称、令牌){
常量邮件选项={
摘自《骑乘共享》,
收件人:电子邮件
};
//用户取消订阅新闻稿。
mailpoptions.subject=`欢迎使用${APP_NAME}!`;
mailOptions.text=`Hey${displayName}!,欢迎使用${APP_NAME}。您的令牌是${token},请在门户中输入令牌以验证帐户。`;
返回mailTransport.sendMail(mailpoptions)。然后(()=>{
console.log('新的欢迎电子邮件发送到:',电子邮件);
});
}
exports.prepareVerificationMail=functions.database.ref('/users/{uid}/shellMailId')
.onWrite((更改、上下文)=>{
console.log('event',change);
log('Mail id为',change.after.val());
if(change.after.val()!=null){
返回change.after.parent.one('value')。然后(函数(快照){
console.log('snapval是用户id',snapshot.key);
var userId=snapshot.key;
//log('这是userId',userId);
返回用户标识;
}).then(函数(用户ID){
log('这应该是用户id',用户id);
返回admin.database().ref().child('userTokens').child(userId).child('token').once('value'))
.then(功能(令牌){
log('这是令牌',令牌);
var displayName=change.after.val().toString();
if(displayName.indexOf('@')>-1){
displayName=displayName.substring(0,displayName.indexOf('@');
}
console.log('displayName',displayName);
返回sendWelcomeEmail(change.after.val()、displayName、token.val());
}).catch(函数(错误){
log('读取用户令牌时出错',错误);
返回;
});
}).catch(函数(错误){
log('获取用户密钥时出错',错误);
返回;
});
}否则{
返回;
}
});
exports.setTheToken=functions.database.ref('/users/{uid}/personalEmail')
.onWrite((更改、上下文)=>{
log('event data val',change.after.val());
控制台日志(更改);
if(change.after.val()!=null){
//
返回change.after.parent.one('value')。然后(函数(快照){
console.log('snapval是用户id',snapshot.key);
var userId=snapshot.key;
//log('这是userId',userId);
返回用户标识;
}).then(函数(用户ID){
log('这应该是用户id',用户id);
var token=parseInt(Math.random()*100000);
log('这是令牌',令牌);
返回admin.database().ref().child('userTokens')。child(userId)。child('token')。set(token)。然后(函数(成功){
log('success token set');
}).catch(函数(错误){
console.log('未设置错误标记',错误);
});
}).catch(函数(错误){
console.log('未设置错误标记',错误);
});
//令牌以前不存在,然后创建并分配
}
否则{
console.log(“个人电子邮件字段值不存在”);
返回;
}
});
exports.removeActiveRequests=functions.https.onRequest((请求、回复)=>{
const key=req.query.key;
//如果钥匙不匹配,退出
if(!secureCompare(key,functions.config().cron.key)){
console.log('请求中提供的密钥与环境中设置的密钥不匹配。请检查',密钥,
'匹配'firebase env:get`'中的cron.key属性;
res.status(403).send('安全密钥不匹配。请确保您的“key”URL查询参数与'+
“cron.key环境变量”。);
返回;
}
log('delete all active requests here');
var userSeatsToUpdate=[];
var firebaseRef=admin.database().ref().child('requests');
返回firebaseRef.one('value')。然后(函数(快照){
snapshot.forEach(函数(子函数){
if(userSeatsToUpdate.indexOf(child.val().requestedTo)<0){
userSeatsToUpdate.push(child.val().requestedTo);
}
});
返回userSeatsToUpdate;
}).然后(功能(成功){
var promises=success.map(函数(键){
返回admin.database().ref().child('users').child(key).once(“value”);
});
返回承诺。全部(承诺);
}).then(功能(快照){
var更新={};
snapshots.forEach(函数(快照){
更新[snapshot.key+“/remainingSeats”]=snapshot.val().capacity;
});
返回更新;
}).then(函数(listToUpdate){
var ref=admin.database().ref().child('users');
返回参考更新(列表更新);
}).然后(功能(成功){
console.log('success',success);
//添加逻辑以移动活动r