【问题标题】:Web firebase.messaging().onMessage not fired, but background notification perfectly firedWeb firebase.messaging().onMessage 未触发,但后台通知完美触发
【发布时间】: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);

});

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

【问题讨论】:

    标签: javascript node.js laravel firebase firebase-cloud-messaging


    【解决方案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】:

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

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

    基本上,全新的开始使用更新的 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 控制台发送通知后,我设法为推送通知调用默认弹出窗口......有什么建议吗?我可以在任何地方共享代码...
      猜你喜欢
      • 2018-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-27
      • 2014-09-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多