如何在使用Firebase Cloud功能创建用户后发送电子邮件验证?

Dav*_*ide 1 email-verification firebase firebase-authentication

我正在尝试在创建用户后发送验证邮件.由于Firebase本身没办法,我正在尝试使用云功能.

我真的找不到很多关于它的文档.我到目前为止尝试做的是:

exports.sendEmailVerification = functions.auth.user().onCreate(event => {
    return user.sendEmailVerification()
});
Run Code Online (Sandbox Code Playgroud)

但是我得到了用户未定义的错误.

我该如何创建这个功能?

谢谢!

Fra*_*len 6

正如@Alexander回答并评论的那样,只有已登录的用户才能请求发送验证邮件.目前无法通过Cloud Functions使用的Admin SDK执行此操作,因为这很容易被滥用.

如果您希望将此功能添加到Admin SDK,我建议您提交功能请求.

在此期间,您可以使用云功能实施自己的电子邮件验证流程.从用户那里获得验证码后,您可以将其emailVerified属性设置为true使用Admin SDK.有关示例,请参阅Firebase文档的此部分.

或者,您也可以通过自己的机制发送电子邮件,但通过生成正确的电子邮件验证链接来使用现有的验证流程

  • 谢谢.这使得Firebase在生产阶段毫无用处.我将提交功能请求,但我还会评估Firebase的替代方案. (3认同)
  • 我想我会在用户第一次登录时发送它! (2认同)

Ram*_*i H 5

这就是我使用 Firebase 云功能和小型快速后端服务器成功实现它的方式

Firebase 云函数(后台)随着每个新用户的创建而触发

  • 此函数将“用户”对象发送到您的 api 端点

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

// Send email verification through express server
exports.sendVerificationEmail = functions.auth.user().onCreate((user) => {
  // Example of API ENPOINT URL 'https://mybackendapi.com/api/verifyemail/'
  return fetch( < API ENDPOINT URL > , {
      method: 'POST',
      body: JSON.stringify({
        user: user
      }),
      headers: {
        "Content-Type": "application/json"
      }
    }).then(res => console.log(res))
    .catch(err => console.log(err));
});
Run Code Online (Sandbox Code Playgroud)

服务器中间件代码

  • 这里的 verifyEmail 用作中间件

// File name 'middleware.js'
import firebase from 'firebase';
import admin from 'firebase-admin';

// Get Service account file from firebase console
// Store it locally - make sure not to commit it to GIT
const serviceAccount = require('<PATH TO serviceAccount.json FILE>');
// Get if from Firebase console and either use environment variables or copy and paste them directly
// review security issues for the second approach
const config = {
  apiKey: process.env.APIKEY,
  authDomain: process.env.AUTHDOMAIN,
  projectId: process.env.PROJECT_ID,
};
// Initialize Firebase Admin
admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
});

// Initialize firebase Client
firebase.initializeApp(config);

export const verifyEmail = async(req, res, next) => {
  const sentUser = req.body.user;
  try {
    const customToken = await admin.auth().createCustomToken(sentUser.uid);
    await firebase.auth().signInWithCustomToken(customToken);
    const mycurrentUser = firebase.auth().currentUser;
    await mycurrentUser.sendEmailVerification();
    res.locals.data = mycurrentUser;
    next();
  } catch (err) {
    next(err);
  }
};
Run Code Online (Sandbox Code Playgroud)

服务器代码

// Filename 'app.js'
import express from 'express';
import bodyParser from 'body-parser';
// If you don't use cors, the api will reject request if u call it from Cloud functions
import cors from 'cors';
import {
  verifyEmail
} from './middleware'

app.use(cors());
app.use(bodyParser.urlencoded({
  extended: true,
}));
app.use(bodyParser.json());

const app = express();
// If you use the above example for endpoint then here will be
// '/api/verifyemail/'
app.post('<PATH TO ENDPOINT>', verifyEmail, (req, res, next) => {
  res.json({
    status: 'success',
    data: res.locals.data
  });
  next()
})
Run Code Online (Sandbox Code Playgroud)

此端点将返回完整的用户对象并将验证电子邮件发送给用户。

我希望这有帮助。