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

How to send email verification after user creation with Firebase Cloud functions?

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

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

exports.sendEmailVerification = functions.auth.user().onCreate(event => {
    return user.sendEmailVerification()
});

但是我收到未定义用户的错误。

如何创建这个函数?

谢谢!

首先查看 Firebase here 的文档。

注册阶段完成并成功后,异步触发以下函数:

 private void sendVerification() {
             FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
             user.sendEmailVerification().addOnCompleteListener(new OnCompleteListener<Void>() {
                @Override
                public void onComplete(@NonNull Task<Void> task) {
                    if (task.isSuccessful()) {
                         system.print.out("Verification Email sent Champion")
                          }
                         }
                });
}

现在将为用户提供验证电子邮件。单击超链接后,您的项目服务器将使用 Firebase 验证用户。

您如何确定用户是否验证了他们的电子邮件?

 private void checkEmail() {

    FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();

    if (user.isEmailVerified()) {
           // email verified ...
    } else {
       // error : email not verified ...
    }
}

遗憾的是,您不能自定义 content/body 验证电子邮件(我一直在与 Firebase 进行大量通信以提供其他不那么丑陋的模板)。您可以更改标题或消息发件人 ID,但仅此而已。

除非您将您的应用程序与您自己支持的网站重新链接,否则不会。 Here.

向用户发送“电子邮件验证”电子邮件有两种可能性:

  1. 登录用户请求发送验证邮件。为此,您从前端调用来自相应客户端 SDK 的 sendEmailVerification() 方法。
  2. 通过其中一个 Admin SDK,您 generate a link for email verification via the corresponding method (e.g. auth.generateEmailVerificationLink() 用于 Node.js Admin SDK) 并且 您通过电子邮件发送 link通过你自己的机制发送。所有这些都在后端完成,并且可以在 Cloud Functions 中完成。

请注意,Admin SDK 的第二个选项与 Client SDK 的第一个选项并不完全相似:在第二个选项中,您需要通过自己的机制发送电子邮件,而在第一种情况下,电子邮件由Firebase平台自动发送

如果您希望将该功能添加到 Admin SDK,我建议您 file a feature request

这就是我使用 Firebase 云函数和小型 express 后端服务器成功实现它的方法

每创建一个新用户都会触发 Firebase Cloud 函数(后台)

  • 此函数将 "user" 对象发送到您的 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));
});

服务器中间件代码

  • 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);
  }
};

服务器代码

// 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()
})

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

希望对您有所帮助。

Version 6.2.0 of the Node.js Admin SDK on November 19, 2018 it is possible to generate, in a Cloud Function, a link for email verification via the auth.generateEmailVerificationLink() 方法发布以来。

您将在 documentation 中找到更多详细信息和一些代码示例。

然后您可以通过 Mailgun、Sendgrid 或任何其他电子邮件微服务发送包含此 link 的电子邮件。您会在此处找到 Cloud Function sample,它展示了如何从 Cloud Functions 发送电子邮件。

如果您想让 Admin SDK 执行此操作,目前除了生成电子邮件验证 link 并使用您自己的电子邮件传送系统发送外别无选择。

然而

您可以在云函数上写REST请求,通过这种方式发起邮箱验证邮件。

export async function verifyEmail(apiKey : string, accessToken : string) {
    // Create date for POST request
    const options = {
        method: 'POST',
        url: 'https://www.googleapis.com/identitytoolkit/v3/relyingparty/getOobConfirmationCode',
        params: {
            key: apiKey
        },
        data: {
            requestType     : "VERIFY_EMAIL",
            idToken         : accessToken
        }
    };

    return await processRequest(options); //This is just to fire the request
}

注册后,将访问令牌传递给此方法,它应该会向注册用户发送一封邮件。

apiKey :Firebase 控制台中项目设置的常规选项卡中是否列出了“Web API 键” 访问令牌:当前用户的访问令牌(我在内部使用注册休息api,所以可以选择请求令牌作为响应)