代码之家  ›  专栏  ›  技术社区  ›  Shawn Deprey

Firebase云消息传递-无法通过PWA接收消息(Vue+Firebase 8.10.0)

  •  0
  • Shawn Deprey  · 技术社区  · 4 年前

    我在firebase的web应用程序设置(PWA)中遇到了一个障碍/缺口,这在文档中并不清楚。我有一个基于Vue@^2.6.10的现有PWA,正在尝试使用firebase@8.10.0.通过在我的应用程序中使用以下代码,可以很容易地将我的应用程序配置为当firebase在浏览器选项卡中处于活动状态时从firebase接收消息。vue在一个创建的钩子中。

    // Includes for the component
    import firebase from 'firebase/app'
    import 'firebase/app'
    import 'firebase/messaging'
    
    // Within the created hook
    firebase.initializeApp({
      apiKey: "XXXXXXXXXX_XXXXXXXXXXXXXXXXXXXXX",
      authDomain: "xxxx.firebaseapp.com",
      projectId: "xxxx",
      storageBucket: "xxxxxx.appspot.com",
      messagingSenderId: "xxxxxxxxxxxx",
      appId: "x:xxxxxxxxx:web:xxxxxxxxxxx",
      measurementId: "G-xxxxxxxxxxx"
    })
    const firebaseMessaging = firebase.messaging()
    firebaseMessaging.getToken()
    .then((token) => { console.log("Messaging Token: ", token) })
    .catch((err) => { console.log("Messaging error: ", err) })
    firebaseMessaging.onMessage((payload) => {
      console.log("Message in app: ", payload)
    })
    

    当PWA在浏览器窗口/选项卡中处于活动状态时,我能够成功地向我的应用程序发送curl消息。

    curl -X POST --header "Authorization: key=XXXXXXXXXXXX" --Header "Content-Type: application/json" https://fcm.googleapis.com/fcm/send -d '{"to":"XXXXXXXXXXXXX","notification":{"title":"Hello","body":"World","icon":"image/mstile-150x150.png"}}'
    

    enter image description here

    但是,如果我尝试配置PWA,以便通过firebase service worker接收通知,则文档似乎缺少上下文。下面是我正在使用的firebase文档中推荐的service worker配置。

    // Give the service worker access to Firebase Messaging.
    // Note that you can only use Firebase Messaging here. Other Firebase libraries
    // are not available in the service worker.
    importScripts('https://www.gstatic.com/firebasejs/8.10.0/firebase-app.js');
    importScripts('https://www.gstatic.com/firebasejs/8.10.0/firebase-messaging.js');
    
    // Initialize the Firebase app in the service worker by passing in
    // your app's Firebase config object.
    // https://firebase.google.com/docs/web/setup#config-object
    firebase.initializeApp({
      apiKey: "xxxxx_xxxxxxxxxxxxxxx",
      authDomain: "xxxx.firebaseapp.com",
      projectId: "xxxx",
      storageBucket: "xxxx.appspot.com",
      messagingSenderId: "xxxxxxxxxxx",
      appId: "x:xxxx:web:xxxxxxxxxx",
      measurementId: "G-xxxxxxxxxxx"
    });
    
    // Retrieve an instance of Firebase Messaging so that it can handle background
    // messages.
    const messaging = firebase.messaging();
    

    对于一个没有现有服务人员的标准网站,这种配置似乎已经足够了,然而,由于我正在与现有服务人员绑定一个现有的PWA,似乎我需要在我的应用程序上用现有的PWA配置注册firebase的配置。从目前为止我发现的情况来看,这种连接的正确配置如下。

    if ("serviceWorker" in navigator) {
      wb = new Workbox(`${process.env.BASE_URL}service-worker.js`)
      wb.addEventListener("controlling", () => { window.location.reload() })
      wb.register()
      wb.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 );
        })
    } else {
      wb = null
    }
    

    从外观上看,这确实成功地向我现有的服务人员注册了Firebase的配置。

    enter image description here

    然而,虽然注册从一开始就看起来很成功,但实际上并没有与服务人员挂钩。在该配置下,当从PWA的活动浏览器选项卡上单击时,服务人员在执行上述相同的旋涡时不会收到通知。从我目前在文档中所能说的一切来看,PWA应该会收到通知并为事件触发默认浏览器通知,然而,事实并非如此。即使通知通过Firebase的API成功发送,但未收到任何通知,因为他们的API做出了响应:

    {"multicast_id":3069325822032476405,"success":1,"failure":0,"canonical_ids":0,"results":[{"message_id":"88f73357-6a0e-416d-8417-67608437f84d"}]}%
    

    所以,就目前为止我能找到的关于这个主题的文档和线索而言,我已经走到了尽头。似乎没有一个很好的例子来说明如何在与现有服务人员绑定时正确地进行此配置。我非常感谢在这方面有经验的人提供他们对您在PWAs上使用firebase和service worker所做配置的见解。

    非常感谢!

    0 回复  |  直到 4 年前
        1
  •  1
  •   Guilherme Maia    4 年前

    初始化Firebase的一种方法 应用程序 和 服务人员 级别是使用消息API和( 邮递 )和软件注册生命周期( 准备好的 ).

    编辑现有的软件文件,而不是为Firebase创建专用软件文件。

    服务人员。js

    importScripts('https://www.gstatic.com/firebasejs/8.10.0/firebase-app.js');
    importScripts('https://www.gstatic.com/firebasejs/8.10.0/firebase-messaging.js');
    
    /**
     * Service Worker message listener.
     */
    self.addEventListener("message", ({ data }) => {
      if (data.action === "initializeFirebase") {
        if (firebase.messaging.isSupported()) {
          const { config } = data.payload;
    
          firebase.initializeApp(config);
          firebase.messaging();
        }
      }
    });
    
    

    它会监听一个名为 initializeFirebase ,接收配置对象,并对其进行初始化。

    --

    现在,我们只需要在服务人员准备好后发送该消息。

    注册服务人员。js (通常是进口的) src/main.js 在Vue项目中。)

    import { register } from "register-service-worker";
    
    import { FirebaseMessaging } from "./FirebaseMessaging.js";
    
    register(`${process.env.BASE_URL}service-worker.js`, {
      ready(registration) {
        FirebaseMessaging.initServiceWorker(registration);
      },
    });
    

    FirebaseMessaging。js

    const FIREBASE_CONFIG = {
      apiKey: "XXXXXXXXXX_XXXXXXXXXXXXXXXXXXXXX",
      authDomain: "xxxx.firebaseapp.com",
      projectId: "xxxx",
      storageBucket: "xxxxxx.appspot.com",
      messagingSenderId: "xxxxxxxxxxxx",
      appId: "x:xxxxxxxxx:web:xxxxxxxxxxx",
      measurementId: "G-xxxxxxxxxxx"
    };
    
    // Firebase Messaging instance
    let messaging;
    
    export const FirebaseMessaging = {
      init() {
        if (!messaging) {
          firebase.initializeApp(FIREBASE_CONFIG);
          messaging = firebase.messaging();
        }
      },
    
      initServiceWorker(registration) {
        this.init();
        messaging.useServiceWorker(registration);
    
        if (registration.active) {
          registration.active.postMessage({
            action: "initializeFirebase",
            payload: { config: FIREBASE_CONFIG },
          });
        }
      }
    };
    

    --

    这样,当注册的软件准备就绪时,Firebase将在应用程序和服务工作者范围内初始化。