我正在我的React应用程序中测试Firebase Cloud Messaging 功能,该功能是使用create-react-app引导的。请注意,我已经正确初始化了 firebase(包括服务器端的管理 SDK),并且我的客户端部署在 https 上。到目前为止,我所做的是:
- 在 firebase.js 中初始化 Firebase 消息传递,并请求通知权限并监听 onMessage 事件
const messaging = firebase.messaging();
messaging
.requestPermission()
.then(() => {
console.log("Permission granted!");
})
.catch(() => {
console.log("Permission denied!");
});
messaging.onMessage(payload => {
console.log("onMessage: ", payload);
});
- 在公共目录中创建服务工作者文件 firebase-messaging-sw.js
importScripts("https://www.gstatic.com/firebasejs/4.8.1/firebase-app.js");
importScripts("https://www.gstatic.com/firebasejs/4.8.1/firebase-messaging.js");
var config = {
messagingSenderId: <messageID hidden>
};
firebase.initializeApp(config);
const messaging = firebase.messaging();
- 我从另一篇 Stackoverflow 帖子中读到,在创建反应应用程序帖子中,这也有必要包含在索引中.js
if ("serviceWorker" in navigator) {
navigator.serviceWorker
.register("../firebase-messaging-sw.js")
.then(function(registration) {
console.log("Registration successful, scope is:", registration.scope);
})
.catch(function(err) {
console.log("Service worker registration failed, error:", err);
});
}
- 为了轻松测试消息传递,我在 Main 中添加了一个按钮.js该按钮将在单击时将令牌发送到我的服务器(然后服务器将继续发送消息)
const handlePushButtonClick = () => {
messaging.getToken().then(token => {
axios.post(<Server link hidden>, {
token
});
});
};
- 然后我在快速服务器中设置了必要的路由,如下所示
app.post("/api/push", async (req, res) => {
const registrationToken = req.body.token;
var message = {
data: {
score: "850",
time: "2:45"
},
token: registrationToken
};
fb.admin
.messaging()
.send(message)
.then(response => {
console.log("Successfully sent message:", response);
res.sendStatus(200);
})
.catch(error => {
console.log("Error sending message:", error);
});
});
问题是,我已经验证了我的服务器已成功接收令牌,实际上已成功发送消息,但在我的客户端,我根本没有收到onMessage有效负载对象。
回想一下我的代码,我希望在客户端开发控制台上收到的是一个控制台.log其中包含 onMessage 和有效负载。
messaging.onMessage(payload => {
console.log("onMessage: ", payload);
});
简单的解决方案是将您的Firebse更新到最新版本。
例如。
importScripts('https://www.gstatic.com/firebasejs/7.8.0/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/7.8.0/firebase-messaging.js');
注意:更新 Firebase 库版本后,消息传递 SenderId将无法在firebase-messaging-sw.js文件中运行。您必须提供所有其他参数,例如。apiKey,projectId,appId 以及messagingSenderId。
例如。
在你的火碱消息传递软件中替换它.js
firebase.initializeApp({
messagingSenderId: "Sender ID"
});
有了这个
firebase.initializeApp({
apiKey: "api-key",
authDomain: "project-id.firebaseapp.com",
databaseURL: "https://project-id.firebaseio.com",
projectId: "project-id",
storageBucket: "project-id.appspot.com",
messagingSenderId: "sender-id",
appId: "app-id",
});
- 如果仍然不起作用。清理浏览器缓存并重新注册服务辅助角色。
我已经发现了我的错误。我最初遵循本指南:https://firebase.google.com/docs/cloud-messaging/js/topic-messaging。当我按照教程进行操作时,我的错误以前不是很清楚,但这可能是因为我对通知和推送 Web API 非常陌生。
本教程的消息对象内部有一个数据对象:
var message = {
data: {
score: '850',
time: '2:45'
},
token: registrationToken
};
事实证明,如果我想在消息中发送数据有效负载,我需要在我的 firebase-messaging-sw 中包含这堆代码.js(我链接的教程中没有显示这一点):
messaging.setBackgroundMessageHandler(payload => {
const title = payload.data.title;
const options = {
body: payload.data.score
};
return self.registration.showNotification(title, options);
});
请注意,仅当您要发送数据负载(此后可以在服务工作线程文件中灵活操作)时,才需要 service worker 文件中的上述代码。如果您只需要发送通知,则消息对象应该只包含一个通知对象(只能接受一些固定键):
var message = {
notification: {
title: '850',
body: '2:45'
},
token: registrationToken
};
如果Maheshvirus提供的答案对某人不起作用,这是对我有用的Firebase的最新版本。
importScripts('https://www.gstatic.com/firebasejs/9.0.0/firebase-app-compat.js');
importScripts('https://www.gstatic.com/firebasejs/9.0.0/firebase-messaging-compat.js');
同样,您必须使用所有详细信息初始化Firebase应用程序才能正常工作。