草庐IT

javascript - 发送推送通知时未调用 messaging.onMessage() (JavaScript)

coder 2024-05-14 原文

我在 Stackoverflow 上发现了一个类似的问题,但不幸的是没有人回答。

我正在尝试使用 FCM 向 Web 发送推送通知。我已经设置了我的应用程序服务器,当我放置 Android 设备的 token 并且通知已成功传递到所有 token 时,它工作正常。但是,当通知发送到 Web 时,不会调用 Web 上的 onMessage() 函数。

我的代码是:

<script src="https://www.gstatic.com/firebasejs/4.6.0/firebase.js"></script>
       <script>
         // Initialize Firebase
         var config = {
           apiKey: "xxxxxxxxx",
           authDomain: "xxxxxxxx",
           databaseURL: "xxxxxxx",
           projectId: "xxxxxxxxxxxx",
           storageBucket: "xxxxxxxxx",
           messagingSenderId: "xxxxxxxxx"
         };
         firebase.initializeApp(config);

           //Get Token
          const messaging = firebase.messaging();
          messaging.requestPermission()
           .then(function () {
               console.log('Have permission');
               return messaging.getToken();
           })
        .then(function (token) {
            console.log(token);
        })
          .catch(function (err) {
              console.log('Error occurred');
          });

          messaging.onMessage(function (payload) {
              console.log('onMessage', payload);
          })

firebase-messaging-sw.js 代码:

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

var config = {
apiKey: "xxxxxxxxx",
authDomain: "XXXXXXXXXX",
databaseURL: "XXXXXXXXXX",
projectId: "XXXXXXXXXX",
storageBucket: "XXXXXXXXX",
messagingSenderId: "XXXXXXXXXX"
};

firebase.initializeApp(config);

const messaging = firebase.messaging();

我不知道哪里出了问题。

最佳答案

当我尝试开始时,我发现这个主题的文档非常少,以至于我几次差点放弃,所以希望阅读本文的其他人可能会发现它有用。

推送通知的整个概念变得更加困惑,因为实际上涉及协同工作的不同 Web API,而且这一点通常不清楚。然后是关于您应该使用 VAPID 还是 FCM 的争论?使用 FCM 的 VAPID 怎么样?哇哇哇哇。

因此,首先您需要处理检查/获取用户通知权限、创建/更新订阅、保存 token 等。如果您正在获取 token /订阅,那么您已准备好向客户端发送数据(这是 Push API 的东西)。

从技术上讲,如果您的用户永远不会离开您的网站,这就是您所需要的,但显然他们会离开,所以这就是您需要 Service Worker 的原因。 Service Worker 可以在用户没有打开您的站点的情况下接收您的推送数据,然后对其进行处理。 (这是 Push/Service Worker API 的交叉)。

最后,您希望您的用户看到您向他们发送的消息,对吗? Push API 将你的消息数据发送给你的 service worker,但你仍然需要处理这些数据。您可能想要显示通知,因此您需要 Notification API。

现在,看看您的代码,您似乎正在前端执行第一部分并为您的用户获取 token ,但您的服务工作线程实际上不包含任何代码,因此它什么也不做。我知道 Firebase 有一些自定义事件处理程序,但标准的网络推送事件处理程序也应该可以工作。

您需要开始的只是在您的 Service Worker 代码中处理推送事件的基本处理程序,如下所示:

self.addEventListener('push', function(event) {
    const push = event.data.json();
    const title = push.data.title;
    const options = JSON.parse(push.data.options);
    event.waitUntil(registration.showNotification(title, options));
});

这样做的好处是保持代码简单,而不是在服务工作线程中硬编码任何通知选项,它允许您的服务器端代码动态自定义每个通知的行为和外观。 Service Worker 实际上只是解析推送负载的 JSON 输入并使用负载中的选项创建通知

您可以找到通知 API 的可用选项列表 here ,它们仍在变化,但截至目前,以下 PHP 示例与上面的服务 worker 代码一起将通过 Firebase 发送功能相当齐全的通知:

$push['to'] = $SUBSCRIBED-FCM-TOKEN;
$push['data']['title'] = 'Here is my title';
$push['data']['options']['body'] = 'and here is the body message';
$push['data']['options']['badge'] = '/images/chaticon.png';
$push['data']['options']['requireInteraction'] = true;
$push['data']['options']['tag'] = 'notification-tag';
$push['data']['options']['icon'] = '/images/icons/256.jpg';
$push['data']['options']['vibrate'] = array(500,150,500,150,500);
$push['data']['options']['image'] = '/images/logo.jpg';
$push['data']['options']['actions'] = array(array('action' => 'accept-action', 'title' => 'Yes', 'icon' => '/images/icons/yes.jpg' ), array('action' => 'reject-action', 'title' => 'No', 'icon' => '/images/icons/no.jpg'));
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://fcm.googleapis.com/fcm/send");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($push));
curl_setopt($ch, CURLOPT_POST, 1);
$headers = array();
$headers[] = "Content-Type: application/json";
$headers[] = "Authorization: key=$SERVER-KEY-FROM-FIREBASE-CONSOLE";
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
curl_close ($ch);

显然,这只是一个基本的示例,您可以选择添加获取事件以响应对您的通知操作的点击等,以执行进一步的操作,用于分析或其他任何操作。您还可以根据用户是否已经在您的网站上来更改行为。

关于javascript - 发送推送通知时未调用 messaging.onMessage() (JavaScript),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47097720/

有关javascript - 发送推送通知时未调用 messaging.onMessage() (JavaScript)的更多相关文章

  1. ruby-on-rails - Rails 常用字符串(用于通知和错误信息等) - 2

    大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje

  2. 使用 ACL 调用 upload_file 时出现 Ruby S3 "Access Denied"错误 - 2

    我正在尝试编写一个将文件上传到AWS并公开该文件的Ruby脚本。我做了以下事情:s3=Aws::S3::Resource.new(credentials:Aws::Credentials.new(KEY,SECRET),region:'us-west-2')obj=s3.bucket('stg-db').object('key')obj.upload_file(filename)这似乎工作正常,除了该文件不是公开可用的,而且我无法获得它的公共(public)URL。但是当我登录到S3时,我可以正常查看我的文件。为了使其公开可用,我将最后一行更改为obj.upload_file(file

  3. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  4. jquery - 我的 jquery AJAX POST 请求无需发送 Authenticity Token (Rails) - 2

    rails中是否有任何规定允许站点的所有AJAXPOST请求在没有authenticity_token的情况下通过?我有一个调用Controller方法的JqueryPOSTajax调用,但我没有在其中放置任何真实性代码,但调用成功。我的ApplicationController确实有'request_forgery_protection'并且我已经改变了config.action_controller.consider_all_requests_local在我的environments/development.rb中为false我还搜索了我的代码以确保我没有重载ajaxSend来发送

  5. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

  6. ruby - 调用其他方法的 TDD 方法的正确方法 - 2

    我需要一些关于TDD概念的帮助。假设我有以下代码defexecute(command)casecommandwhen"c"create_new_characterwhen"i"display_inventoryendenddefcreate_new_character#dostufftocreatenewcharacterenddefdisplay_inventory#dostufftodisplayinventoryend现在我不确定要为什么编写单元测试。如果我为execute方法编写单元测试,那不是几乎涵盖了我对create_new_character和display_invent

  7. ruby - 使用 Ruby 通过 Outlook 发送消息的最简单方法是什么? - 2

    我的工作要求我为某些测试自动生成电子邮件。我一直在四处寻找,但未能找到可以快速实现的合理解决方案。它需要在outlook而不是其他邮件服务器中,因为我们有一些奇怪的身份验证规则,我们需要保存草稿而不是仅仅发送邮件的选项。显然win32ole可以做到这一点,但我找不到任何相当简单的例子。 最佳答案 假设存储了Outlook凭据并且您设置为自动登录到Outlook,WIN32OLE可以很好地完成此操作:require'win32ole'outlook=WIN32OLE.new('Outlook.Application')message=

  8. ruby-on-rails - 如何在发布新的 Ruby 或 Rails 版本时收到通知? - 2

    有人知道在发布新版本的Ruby和Rails时收到电子邮件的方法吗?他们有邮件列表,RubyonRails有一个推特,但我不想听到那些随之而来的喧嚣,我只想知道什么时候发布新版本,尤其是那些有安全修复的版本。 最佳答案 从therailsblog获取提要.http://weblog.rubyonrails.org/feed/atom.xml 关于ruby-on-rails-如何在发布新的Ruby或Rails版本时收到通知?,我们在StackOverflow上找到一个类似的问题:

  9. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  10. C51单片机——实现用独立按键控制LED亮灭(调用函数篇) - 2

    说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时

随机推荐