【问题标题】:Vue pwa with firebase cloud messaging not working properly带有 Firebase 云消息传递的 Vue pwa 无法正常工作
【发布时间】:2018-10-10 06:57:05
【问题描述】:

我正在尝试以下代码:

    navigator.serviceWorker.register('service-worker.js')
      .then((registration) => {
        const messaging = firebase.messaging().useServiceworker(registration)
        console.log(messaging)
        messaging.requestPermission().then(function () {
          console.log('Notification permission granted.')
          messaging.getToken().then(function (currentToken) {
            if (currentToken) {
              console.log(currentToken)
            }
          })
        })
      })

我的清单:

{
  "name": "Herot-Eyes",
  "short_name": "herot-eyes",
  "gcm_sender_id": "103953800507",
  "icons": [
    {
      "src": "/static/img/icons/herot-eyes-192x192.png",
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "/static/img/icons/herot-eyes-512x512.png",
      "sizes": "512x512",
      "type": "image/png"
    },
    {
      "src": "/static/img/icons/apple-touch-icon-180x180.png",
      "sizes": "180x180",
      "type": "image/png"
    }
  ],
  "start_url": "/",
  "display": "fullscreen",
  "orientation": "portrait",
  "background_color": "#000000",
  "theme_color": "#2196f3"
}

出了什么问题?我的 console.log(messaging) 返回工厂错误,如下:

bad-push-set : "用于存储/查找的 FCM 推送集不是 一个有效的推送集字符串。" bad-scope

"Service Worker 范围必须是一个字符串,其中至少有一个 字符。”错误的发件人 ID

"请确保 'messagingSenderId' 在 传递给 firebase.initializeApp() 的选项。" 订阅错误

“订阅必须是有效的 PushSubscription。”坏令牌:“ 用于存储/查找的 FCM 令牌不是有效的令牌字符串。” 错误的密钥

“公共 VAPID 密钥不是 65 字节的 Uint8Array。” bg-handler-function-expected

“setBackgroundMessageHandler() 的输入必须是一个函数。” 删除范围未找到

“无法执行服务工作者范围的删除尝试 因为找不到范围。” delete-token-not-found

"令牌的删除尝试无法作为令牌执行 没有找到。” failed-delete-vapid-key

“无法删除 VAPID 密钥。” 服务工作者注册失败

“我们无法注册默认服务工作者。 {$browserErrorMessage}" 删除令牌失败

“无法删除当前保存的令牌。”获取订阅失败

“尝试获取任何现有推送时出错 订阅。”不正确-gcm-sender-id

“请将您的网络应用清单的 'gcm_sender_id' 值更改为 '103953800507' 使用 Firebase 消息传递。" invalid-delete-token

"您必须将有效的令牌传递给 deleteToken(),即来自的令牌 getToken()." 无效的公共 vapid 密钥

"公共 VAPID 密钥必须是字符串。"无效的保存令牌

“无法访问已保存令牌的详细信息。” no-fcm-token-for-resubscribe

“找不到 FCM 令牌,因此无法重新订阅。 下次访问时必须重新订阅用户。" no-sw-in-reg

"虽然Service Worker注册成功,但还是有 访问 Service Worker 本身时出现问题。” 无窗口客户端到消息

“试图向不存在的窗口客户端发送消息。” 通知被阻止

“通知已被阻止。”仅在 sw 中可用

“此方法在服务工作者上下文中可用。” 仅在窗口中可用

“此方法在 Window 上下文中可用。”权限被屏蔽

“所需的权限没有被授予并被阻止。” 权限默认

“所需的权限没有被授予并被取消。” 公钥解密失败

“解密时,公共 VAPID 密钥不等于 65 个字节。” 应该被覆盖

“这个方法应该被扩展类覆盖。” sw-reg-冗余

“用于推送的 Service Worker 已冗余。” sw-registration-expected

“服务工作者注册是预期的输入。” 令牌订阅失败

“为用户订阅 FCM 时出现问题:{$message}” 令牌订阅无推送设置

“FCM 在获取 FCM 令牌时返回无效响应。” 令牌订阅无令牌

“订阅用户推送时,FCM 未返回任何令牌。” 令牌退订失败

“从 FCM 取消订阅用户时出现问题:{$message}” 令牌更新失败

“从 FCM 更新用户时出现问题:{$message}” 令牌更新无令牌

“更新用户推送时,FCM 未返回令牌。” 无法重新订阅

“重新订阅 FCM 令牌以进行推送时出错 消息传递。下次访问时必须重新订阅用户。 {$message}" 不支持的浏览器

“此浏览器不支持使用 firebase 所需的 API SDK。”使用-sw-before-get-token

"您必须在调用 getToken() 之前调用 useServiceWorker() 以确保 使用了你的 Service Worker。”

【问题讨论】:

标签: firebase vue.js push-notification service-worker progressive-web-apps


【解决方案1】:

配置服务器接收通知

在公用文件夹中,将以下行添加到 ma​​nifest.json

{
    //...manifest properties
    "gcm_sender_id": "103953800507" <--- add this line to the file
}

注意:如果项目不是使用 Vue Cli 创建的,请手动创建 manifest.json 文件。(感谢 @natghi)

firebase-messaging-sw.js

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

var config = {
  messagingSenderId: <Sender ID>
};
firebase.initializeApp(config);

let messaging = firebase.messaging();

在您的 main.js 文件中添加以下代码

var config = {
  apiKey: <API_KEY>,
  authDomain: <DOMAIN>,
  databaseURL: <DATABASE_URL>,
  projectId: <PROJECT_ID>,
  storageBucket: <STORAGE_BUCKET>,
  messagingSenderId: <SENDER_ID>
};
firebase.initializeApp(config);

Vue.prototype.$messaging = firebase.messaging()

navigator.serviceWorker.register('/firebase-messaging-sw.js')
  .then((registration) => {
    Vue.prototype.$messaging.useServiceWorker(registration)
  }).catch(err => {
    console.log(err)
  })

接收通知

然后在你的 App.vue 中,将此代码添加到 created() 函数中

created() {
    var config = {
        apiKey: <API_KEY>,
        authDomain: <DOMAIN>,
        databaseURL: <DATABASE_URL>,
        projectId: <PROJECT_ID>,
        storageBucket: <STORAGE_BUCKET>,
        messagingSenderId: <SENDER_ID>
    };
    firebase.initializeApp(config);
    const messaging = firebase.messaging();

    messaging
    .requestPermission()
    .then(() => firebase.messaging().getToken())
    .then((token) => {
        console.log(token) // Receiver Token to use in the notification
    })
    .catch(function(err) {
        console.log("Unable to get permission to notify.", err);
    });

    messaging.onMessage(function(payload) {
    console.log("Message received. ", payload);
    // ...
    });
}

发送通知

更新

const admin = require("firebase-admin")

var serviceAccount = require("./certificate.json");

admin.initializeApp({
    credential: admin.credential.cert(serviceAccount),
});
const Messaging = admin.messaging()

var payload = {
    webpush: {
        notification: {
            title: "Notification title",
            body: "Notification info",
            icon: 'http://i.imgur.com/image.png',
            click_action: "http://yoursite.com/redirectPage" 
        },
    },
    topic: "Doente_" + patient.Username
};

return Messaging.send(payload)

旧版本

然后,在邮递员中,您执行以下请求

POST /v1/projects/interact-f1032/messages:send HTTP/1.1
Host: fcm.googleapis.com
Authorization: Bearer <SENDER_TOKEN>
Content-Type: application/json

{
  "message":{
    "token" : The token that was in the console log,
    "notification" : {
      "body" : "This is an FCM notification message!",
      "title" : "FCM Message"
      }
   }
}

发件人令牌

在您的后端,使用以下代码,其中文件“certificate.json”在 firebase 仪表板中获得(https://firebase.google.com/docs/cloud-messaging/js/client - 生成密钥对)

const {google} = require('googleapis');

function getAccessToken() {
  return new Promise(function(resolve, reject) {
    var key = require('./certificate.json');
    var jwtClient = new google.auth.JWT(
      key.client_email,
      null,
      key.private_key,
      ["https://www.googleapis.com/auth/firebase", 
      "https://www.googleapis.com/auth/cloud-platform"],
      null
    );
    jwtClient.authorize(function(err, tokens) {
      if (err) {
        reject(err);
        return;
      }
      resolve(tokens.access_token);
    });
  });
}

getAccessToken().then(senderToken => console.log(senderToken))

在 Authorization 标头上使用 senderToken 来发送通知

【讨论】:

  • 您更新的解决方案几乎可以正常工作。如果我使用您提供的代码,您将收到 firebase 已初始化的错误。因此,您需要在 App.vue 中使用 this.$messaging 而不是重新初始化 firebase。这对我有用。
  • 替换 var config = { apiKey: , authDomain: , databaseURL: , projectId: , storageBucket: , messingsSenderId: }; firebase.initializeApp(config);有了这个.$messaging ?因为我的代码在我测试时可以正常工作
  • 你能帮我如何获取certificate.json这个文件
  • @DarshanDave firebase.google.com/docs/admin/setup#add_firebase_to_your_app 在这里你可以得到证书
  • 此解决方案完美运行。谢谢!我认为你应该澄清的唯一一件事是 { "gcm_sender_id": "103953800507" } 应该进入 CLI 已经创建的对象(如果已经有一个)。我犯了两个对象的错误,这导致了错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-04
  • 1970-01-01
  • 1970-01-01
  • 2018-05-27
相关资源
最近更新 更多