Next.js API 路由 + Node-APN:无法获取 .p8 Apple 密钥文件的路径以在部署到 Vercel 后发送推送通知

问题描述

在我的 Next.js 应用程序中,我希望能够从请求正文中获取 iOS 设备令牌,并在有人点击我在 /pages/api/sendPushNotification.ts 中创建的端点时向这些令牌发送通知。我正在使用 node-apn 包 (https://www.npmjs.com/package/apn) 在我的 Node.js 服务器代码(位于 pages/api/sendPushNotification.ts 中)和 Apple 推送通知服务之间建立连接。我已经有了我的 .p8 key file 并且我知道它可能不应该被提交,但我想不出任何其他方式来传递它的路径。我有它位于/public/apn/AuthKey.p8。当我将 .p8 key file 的本地绝对路径node-apn 包传递到此配置时,一切都在本地正常运行:

var options = {
  token: {
    key: "path/to/APNsAuthKey_XXXXXXXXXX.p8",keyId: "key-id",teamId: "developer-team-id"
  },production: true
};

但是,在 Vercel 上将我的项目部署到生产环境后,找不到 .p8 key file 并且我总是收到一条错误消息: VError: Failed loading token key: ENOENT: no such file or directory,open '/apn/AuthKey.p8'

我遵循了本教程: https://medium.com/@boris.poehland.business/next-js-api-routes-how-to-read-files-from-directory-compatible-with-vercel-5fb5837694b9 当试图实现它但没有成功时。

我在 /pages/api/sendPushNotification.ts 中的代码如下所示:

const apn = require("apn");
import fs from "fs";
import path from "path";

export default async (req,res) => {
  const dirRelativetoPublicFolder = "apn";
  const dir = path.resolve("./public",dirRelativetoPublicFolder);
  const filename = fs.readdirsync(dir);

  const authKey = path.join("/",dirRelativetoPublicFolder,filename[0]);

  const { iosTokens } = req.body;

  res.statusCode = 200;
  res.json({
    message: "Notification sent!",});

  if (iosTokens?.length !== 0) {
    const apnoptions = {
      token: {
        key: authKey,keyId: process.env.NEXT_PUBLIC_APN_KEY_ID,teamId: process.env.NEXT_PUBLIC_APN_TEAM_ID,},production: true,};

    const apnProvider = new apn.Provider(apnoptions);

    const note = new apn.Notification();
    note.alert = {
      title: "XXXXX",body: "XXXXXXXXXX",};
    note.sound = "default";
    note.topic = "XXXXXXX";

    console.log(
      `Attempting to send the notification to ${iosTokens.length} iOS devices.`
    );

    iosTokens.forEach((devicetoken) => {
      apnProvider
        .send(note,devicetoken)
        .then((result) => {
          console.log(result);
        })
        .catch((error) => {
          console.log(
            "Error occured when trying to send notification: ",error
          );
        });
    });
  }
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)