FCM 在本地主机上工作,但不在生产环境中工作

问题描述 投票:0回答:1

我利用 FCM 在我的网络应用程序中发送通知。我可以在本地主机中发送和接收通知,因此一切都在本地主机上完美运行。但是,我只能接收通知(从 firebase 控制台、邮递员等发送),但不能在生产中的部署版本上发送它们。

我正在使用 Vercel 托管我的服务器,并使用 Vercel 的 API 路由。我在本地和 Vercel 中都有相同的环境变量。在浏览器上,当我记录它们时,我也从 API 路由获得相同的响应(均为 success 200)。唯一的区别是,当我从生产版本发送通知时,不会出现通知。另外,无论出于何种原因,Vercel 都没有显示任何服务器端日志,因此我什至无法调试。

有谁知道为什么会发生这种情况以及我该如何解决它?

我的 Next.js 应用程序的 API 文件夹中的 API/发送路由

import { NextResponse } from 'next/server'
import { getFirestore } from 'firebase-admin/firestore'
import { initAdmin } from '@/db/firebaseAdmin'
import { getMessaging } from 'firebase-admin/messaging';

export async function GET (req: Request, res: Response) {

    // Initialize Firebase Admin
    const app = await initAdmin();

    // get current time
    const currentTime = new Date();

    try {
        const registrationTokens = [
            'f3QNNQiLrpA4n1ayL46sz6:APA91bE-Zy9ypgl6R9nmBKYc_KgrhZs6sD3NqzEG6pLIsaGEQF2wrPSZpO-MWwanAnP0eHUGmCy2PqesD7ZR3IWNO1uumO3-KAvcjMqFWZ3aFpzaoUGa9UKSUtSP3Zgj0LpePuPluf4T', // mobile
            'fWRzguAj87BidFhkNCRdUP:APA91bEfsz8d8XSPW3SOG862V968wvn3vOhu_eJiIG2pGp4a_MrwzUUapzNg8BKvoMuF2FXqFo1f0-YlKjJSqnyf7Y_YfhbTFB8X-PsxcHJ2oOHtUAa-aQHsZg9AK5LcQqOrir9k4X56', // localhost
            'faggSiQojS1TTnljfWE1R7:APA91bHTSLOpEykD75JB_0pyqAautPijFyeLXebor8nVguBHxmvj-eMJzYe6PW51sOoPK4KzAJJlHPc9x-jcFyRurggvXhSFzF8jPtJYfog4RCQSMC1Mi12bRgamCBhSdGz5Rcmhkya9' // deployed desktop
          ];

        const message = {
            notification: {
              title: currentTime.toString(),
              body: "message"
            }
        };

        // Initialize Messaging
        const messaging = getMessaging(app);

        // Send a message to the devices corresponding to the provided registration tokens.
        const sendPromises = registrationTokens.map(token => {
            return messaging.send({ ...message, token: token });
        });

        // Use Promise.all to wait for all messages to be sent
        const responses = await Promise.all(sendPromises);

        console.log('Successfully sent messages:', responses);

        return NextResponse.json({
            message: "Notifications sent",
            responses: responses
        });
    } catch (error: any) {
        console.error('An error occurred while sending notifications:', error);
        return NextResponse.json(
            { message: error.message || 'Internal Server Error' },
            { status: 500 }
        );
    }
}

firebase next.js firebase-cloud-messaging vercel
1个回答
0
投票

我亲爱的开发同事 Tom,我对 Vercel 也有同样的问题。但我现在找到了一个解决方法 - >避免使用“firebase-admin”。 对我来说,它可以工作,但在 Vercel 上是随机的,在本地主机上零问题。

这是我当前的设置,效果非常好,希望对您有所帮助:

//生成token

const {JWT} = require('google-auth-library');
const firebaseEmail = process.env.FIREBASE_EMAIL;
const firebasePrivateKey = process.env.FIREBASE_PRIVATE_KEY.replace(/\\n/g, '\n');

async function generateAccessToken() {
    const client = new JWT(
        firebaseEmail,
        null,
        firebasePrivateKey,
        ['https://www.googleapis.com/auth/cloud-platform'],
        null
    );
    await client.authorize();
    return client.getAccessToken();
}

//使用FCM HTTP v1 API调用

const url = "https://fcm.googleapis.com/v1/projects/your-project-from-fcm/messages:send";
    const GetFirebaseToken = await generateAccessToken();
    const headers = {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer ' + GetFirebaseToken.token
    }

    const data = {
        "message": {
            "topic": 'your-topic', //you can replace with device token if you want, but cannot use token and topic together
            "android": {
                "priority": "high"
            },
            "webpush": {
                "headers": {
                    "Urgency": "high"
                },
                "data": {
                    "body": message,
                    "title": `New Title`,
                    "requireInteraction": "true",
                },
                "fcm_options": {
                    "link": "you url"
                }
            }
        }
    }

//最后发送请求,就会弹出你的推送通知

const response = await fetch(url, {
            method: 'POST',
            headers: headers,
            body: JSON.stringify(data)
        });
© www.soinside.com 2019 - 2024. All rights reserved.