Web firebase.messaging().onMessage 未触发,但后台通知完美触发

Posted

技术标签:

【中文标题】Web firebase.messaging().onMessage 未触发,但后台通知完美触发【英文标题】:Web firebase.messaging().onMessage not fired, but background notification perfectly fired 【发布时间】:2020-02-11 16:16:11 【问题描述】:

如果推送消息是使用 firebase.messaging().onMessage 发送的,我想在前台重新加载或触发某些事件,但它没有被触发。我正在使用带有后台通知的 firebase.mesaging.sw.js,它可以正常工作我的代码有什么问题?

firebase.js

const config = 
  apiKey: "x",
  projectId: "x",
  storageBucket: "x",
  messagingSenderId: "x"
;

firebase.initializeApp(config);

const msg = firebase.messaging()
msg.requestPermission()
  .then(() => 
    return msg.getToken()
  )
  .then((token) => 
  )
  .catch((err) => 
  )

msg.onMessage(function(payload) 
  alert("Foreground message fired!")
  console.log(payload)
);

firebase.messaging.sw.js

importScripts("https://www.gstatic.com/firebasejs/7.0.0/firebase-app.js");
importScripts("https://www.gstatic.com/firebasejs/7.0.0/firebase-messaging.js");

const config = 
  apiKey: "x",
  projectId: "x",
  storageBucket: 'x',
  messagingSenderId: "x"
;

firebase.initializeApp(config);
const msg = firebase.messaging()

msg.setBackgroundMessageHandler(function(payload) 
  let options = 
    body: payload.data.body,
    icon: payload.data.icon
  

  return self.registration.showNotification(payload.data.title, options);

);

我不知道我的代码有什么问题

【问题讨论】:

【参考方案1】:

解决此问题的简单方法是将您的 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 库版本,那么 messagingSenderId 将无法在您的 firebase-messaging-sw.js 文件中使用。您必须提供所有其他参数,例如。 apiKey、projectId、appId 以及 messagingSenderId

如果还是不行。清理浏览器缓存并重新注册 Service Worker。

更多详情可以参考这个solution

【讨论】:

很抱歉,但这两种说法似乎都是错误的。后台通知仅通过 SW 中的 messingsSenderId 不断到达,Firebase API 中的升级似乎都没有解决任何问题。 onMessage 事件不会触发。 @andreszs 面临与 firebasejs/7.0.0 版本相同的问题。不触发 onMasage 事件。我已将我的 firebase 版本更新为最新版本。然后我面临着SW中缺少项目ID的问题。所以我已经通过了所有其他细节。然后一切正常。 谢谢,我承认将整个firebaseConfig 添加到您所说的SW 中的initializeApp 方法中,加上清理Chrome 数据和缓存并重新注册通知最终解决了问题。您可以添加缓存清理和重新注册建议来扩展您的答案。【参考方案2】:

对于遇到此问题的其他人,我终于解决了:

    将包含标头的 JS 文件和 SW JS 文件中的 Firebase SDK 版本升级到最新版本(当前为 7.8.1)。 将整个 firebaseConfig 数组添加到 SW firebase.initializeApp(),如上一个答案所示。 从开发者工具的应用程序>清除存储部分清除 Chrome 缓存。 正在从我的数据库中删除以前的注册令牌。 阻止和取消阻止来自浏览器的通知以强制生成新的令牌。

基本上,全新的开始使用更新的 Firebase SDK 似乎可以解决此类问题。

【讨论】:

【参考方案3】:

2020 年仍然有同样的问题。就我而言,情况是这样的:

您需要在 importScripts 中为后台消息和在您的应用程序中为前台消息提供相同的版本 获取后台服务token后调用
firebaseApp.messaging().getToken().then((currentToken) => 
  if (currentToken) 
    console.log(currentToken)
   else 
    // Show permission request.
    console.log(
      'No Instance ID token available. Request permission to generate one.')
  
  /** When app is active */
  firebase.messaging().onMessage((payload) => 
    console.log(payload)
  , e => 
    console.log(e)
  )
)

【讨论】:

感谢onMessagegetToken 为我工作后运行【参考方案4】:

你错过了很多东西,只有在调用它之前初始化 firebase 时 onMessage 才会起作用。请遵循此。我已经这样做了,它正在工作。

初始化firebase并获取token

export class BrowserFcmProvider 
export const FIREBASE_CONFIG = 
 apiKey: "****",
 authDomain: "****",
 databaseURL: "****",
 projectId: "****",
 storageBucket: "****",
 messagingSenderId: "****",
 appId: "****"


firebase.initializeApp(FIREBASE_CONFIG);

async webGetToken() 
 try 
   const messaging = firebase.messaging();
   await messaging.requestPermission();
   const token = await messaging.getToken();
   let uuidTemp = new DeviceUUID().get();
   return this.saveTokenToFireStoreFromWeb(token, uuidTemp)

  catch (e) 
   console.log(e);
 


saveTokenToFireStoreFromWeb(token, uuid) 
  try 
     const docData = 
     token: token,
     device_type: 'web',
     uuid: uuid
     
    const devicesRef = this.db.collection('devices')
    return devicesRef.doc(uuid).set(docData);
   catch (e) 
    console.log(e, 'saveTokenError');
  


showMessage() 
  try 
    const messaging = firebase.messaging();
    messaging.onMessage((payload) => 
    console.log(payload);
    )
   catch (e) 
    console.log(e)
  


并在应用加载时调用该方法

  async configureFirebaseForBrowser(res) 
      await this.bfcm.webGetToken();
      this.bfcm.showMessage();
  

Firebase 函数和负载类型

    const payloadWeb = 
            title: title,
            body: body,
            data: 
                title: title,
                body: body
            ,
            tokens: uniqueDevicesTokenArrayWeb,
        

  const responseWeb = await admin.messaging().sendMulticast(payloadWeb);
  console.log(responseWeb.successCount + ' notifications has been sent to Web successfully');

我使用了 async 和 await,因为我们需要异步管理 firebase/firestore 操作。

fcm 在隐身模式和 safari 浏览器中不起作用

【讨论】:

$scope.init = (startDate, endDate, role, moderation) => webGetToken();显示消息();我已经使用了您的示例,但仍然无法正常工作,已授予 requestPermission 但未触发 onMessage 函数 你有没有得到任何错误?您在哪个框架中使用它?你能正确初始化firebase吗?常量 firebaseIntialise = firebase.initializeApp(FIREBASE_CONFIG); console.log(firebaseIntialise);你得到了什么? 我在 node js 中使用 laravel,我的 firebaseInitialize 工作正常,如果我把它放在一个变量上并控制台它,你会看到一个带有 INTERNAL、firebase、isDeleted、options 等等的对象 laravel 和 nodejs 都适用于服务器端。为什么用两个?你能把它放在 GitHub 上,以便我可以查看并修复它。 你需要将Service Worker中的SDK版本更改为“7.1.0”importScripts('https://www.gstatic.com/firebasejs/7.1.0/firebase-app.js') importScripts('https://www.gstatic.com/firebasejs/7.1.0/firebase-messaging.js')【参考方案5】:

我遇到了同样的问题。在我的情况下, "package.json""firebase-messaging-sw.js" importScripts 版本中的 firebase 版本不同。在 "firebase-messaging-sw.js" importScripts 中设置相同版本后 “package.json”,我的问题已解决。

更改前

 **"package.json"**
 
 "firebase": "^8.2.1",
 
  **"firebase-messaging-sw.js"**

 importScripts('https://www.gstatic.com/firebasejs/7.8.0/firebase-app.js');
 importScripts('https://www.gstatic.com/firebasejs/7.8.0/firebase-messaging.js');

改动后

 **"package.json"**

 "firebase": "^8.2.1",

 **"firebase-messaging-sw.js"**

 importScripts('https://www.gstatic.com/firebasejs/8.2.1/firebase-app.js');
 importScripts('https://www.gstatic.com/firebasejs/8.2.1/firebase-messaging.js');

【讨论】:

我有这些相同的版本,目前是 8.9.1 但我无法获得打印到控制台的通知。在直接从 FCM 控制台发送通知后,我设法为推送通知调用默认弹出窗口......有什么建议吗?我可以在任何地方共享代码...

以上是关于Web firebase.messaging().onMessage 未触发,但后台通知完美触发的主要内容,如果未能解决你的问题,请参考以下文章

错误:无法解决:com.google.firebase:firebase-messaging:19.2.0 [重复]

firebase.messaging().setBackgroundMessageHandler(*) 'handler' 期望一个函数

Flutter:CocoaPods 找不到 pod“Firebase/Messaging”的兼容版本

使用@react-native-firebase/messaging 收到通知后应用程序崩溃

Xamarin Forms 2.3.3.175 和 Xamarin.Firebase.Messaging 不可能?

添加 Firebase/Messaging CocoaPod 会导致 iOS 应用无法构建