当应用程序打开或应用程序处于后台时,Phonegap Firebase 推送通知不会触发事件侦听器

Posted

技术标签:

【中文标题】当应用程序打开或应用程序处于后台时,Phonegap Firebase 推送通知不会触发事件侦听器【英文标题】:Phonegap Firebase Push Notification not firing event listener when app opens, or when app is in background 【发布时间】:2019-08-10 05:16:54 【问题描述】:

我正在使用 Phonegap 和 Firebase (fcm) 来接收推送通知。 我正在使用 android 8 进行测试。

如果应用程序在前台运行,我希望我的设备接收推送通知(作为应用程序中的弹出消息)。 如果应用程序已关闭或在后台,我希望将消息显示为通知,当我单击通知时,它会在前台打开应用程序并调用通知事件函数。

到目前为止发生的情况如下:

当应用打开时,推送通知会出现并显示在应用中 - 正确

当应用程序最小化时,顶部栏中会出现一个推送通知 - 正确...但是

当我单击通知消息时,它会打开我的应用程序/将其置于前台,但未调用“通知”事件侦听器 - 不正确

有很多关于这个问题的帮助请求,我已经处理了很多,但没有一个为我的应用程序提供有效的解决方案(大多数是在 2016 年到 2018 年之间,而不是 2019 年)。

这主要需要适用于 Android。因此,我尝试删除通知有效负载并仅使用数据有效负载。但这并不能解决问题。

这是我当前的有效载荷:

$notification = array
(
'body'   => 'test',
'title'     => 'test',
"icon" =>  'notification_icon',
"content_available" => true,
);

$data = array
(
"title" => "test",
"body" => "test",
"icon" => "notification_icon",
"content_available" => true,
);

$fields = array
(
'registration_ids'  => $registrationIds,
'notification'      => $notification,
'data'          => $data,
"priority" => "high",
"content_available" => true 
);

据我了解,发送通知有 3 种方式:

1) 作为“通知”。如果应用程序当前正在运行,这将在前台工作,如果应用程序已关闭或最小化(并且应用程序的图标上方有一个小徽章,指示消息),则在顶部栏中的后台工作,但在后台时,当点击消息时,应用程序加载但未调用通知功能。

2) 作为“数据”。这似乎只在前台工作,没有顶部栏消息,应用程序的图标上方没有小徽章。如果应用程序在后台,则根本没有推送通知。

3) 作为“通知”和“数据”。在后台时,应用程序图标上方有一个徽章。单击顶部栏消息时,应用程序已加载,但未调用通知功能。

此外,即使应用程序在后台,如果它收到推送通知并将应用程序置于前台,也不会显示通知消息。只有在收到通知时应用已经在前台时才有效。

这是我的事件监听器:

var app = 
initialize: function() 
    this.bindEvents();
,
bindEvents: function() 
    document.addEventListener('deviceready', this.onDeviceReady, false);
,
onDeviceReady: function() 
  console.log('Received Device Ready Event');
  app.setupPush();
,
setupPush: function() 
    var push = PushNotification.init(
      android: 
        senderID: 'XXXXXXXXXX',  
        iconColor: "#ccc",
        alert: true,
        badge: true,
        icon: 'notification_icon',
        sound: true,
        vibrate: true,
      ,
      browser: ,
      ios: 
        sound: true,
        vibration: true,
        badge: true
      ,
      windows: 
    );
    console.log('after init');

    push.on('registration', function(data) 
         //[edit - script not displayed for this example, but it registers a token to enable push notifications to the device. tested and working]
    );

    push.on('error', function(e) 
      console.log('push error = ' + e.message);
    );

    push.on('notification', function(data) 
       window.alert(data.additionalData);              //Test line

      if(data.additionalData.foreground)
        window.alert(data.title+'\n'+data.message);    //Test line
      
      if(data.additionalData.coldstart)
        window.alert("coldstart");                     //Test line
      
      showPopup(data,"info");

    );


  
;

//Using Sweet Alert to display messages

function showPopup(data,type)
   Swal.fire(
     type: type,
     title: data.title,
     text: data.message,
     showConfirmButton: true,
     imageUrl: data.image,
     imageWidth: 400,
     imageHeight: 200,
    imageAlt: data.title,
    animation: true,
  );

有人对上述适用于 Android 7 和 8 的答案有答案吗?

【问题讨论】:

有些人报告说,如果您从有效负载中排除“通知”对象,它将在前台、后台和作为通知的点击中工作。然而,这似乎对 Android 8 没有任何影响,并且排除通知有效负载也会阻止它在 IOS 中工作。 更多信息在这里:github.com/phonegap/phonegap-plugin-push/issues/2575 你能告诉我们你是如何创建和设置事件监听器来接收通知的吗? 嗨,是的,现在会更新问题。 【参考方案1】:

您的通知发送逻辑是可靠的,但您的担忧也是有效的。如果你想阅读更多关于这个主题的内容,googlenotification vs data notifications,这里有一些很好的文章来解释它。

推送通知在开放接收器上有一个特殊的本机,您的 WebView 必须注册这些事件。但是,如果您查看source,则不会处理通知打开事件。除了分叉存储库之外,您无能为力。

此外,当应用程序被终止时,您的 WebView 不会收到 .on('notification') 事件,因为......好吧,您的应用程序被终止了。您的应用程序在被杀死时不会收到通知,Android 操作系统会收到通知并决定如何处理它。

至于您在 Android 8 上注意到此问题的原因,最近版本的 Android 更积极地在后台杀死应用程序以节省电池:Doze 和 Adaptive battery。较新的 Android 应用程序将很快被淘汰。

如果可能,我建议您切换到cordova-plugin-firebase,这是一个维护更积极的插件。或者,学习一点 android 并编写自己的插件。

【讨论】:

感谢您的回复。即使应用程序在后台,它也永远不会收到 on("notification") 事件。也许,正如你所说,由于更积极的节电技术,后台运行的应用程序上的所有事件都被忽略了,只有主前台应用程序会收到任何东西。这对于我正在制作的应用程序来说是一个真正的耻辱。我尝试使用cordova-plugin-firebase,但发现它有很多问题。 正如我所提到的,对于您的情况,是否调用 on("notification") 并不重要。您需要监听 onNotificationOpen 事件,即使您的应用程序被杀死,您也可以使用 cordova-plugin-firebase 来做到这一点。 window.FirebasePlugin.onNotificationOpen 是事件。至于错误,FirebasePlugin 在最新的 Google API 版本(5 月 7 日)中遇到了一些问题。您可以通过修复 project.properties 文件中的依赖项编号来解决此问题(这不是解决方案,而是一种解决方法): cordova.system.library.4=com.google.firebase:firebase-core:16.0.8 cordova.system.library.5=com.google.firebase:firebase-messaging:17.5.0 cordova.system.library.6=com.google.firebase:firebase-config:16.4.1 cordova.system.library.7=com.google.firebase:firebase-perf:16.2.4 太好了,谢谢,我会试一试并回复你【参考方案2】:

我的最终答案是,要让推送消息同时用作 Android 设备(包括 Android 8 和 9)的通知消息和应用内消息,请执行以下操作:

在 config.xml 中添加/修改:

<preference name="phonegap-version" value="cli-9.0.0" />  
<platform name="android">
    <resource-file src="google-services.json" target="app/google-services.json" />
</platform>
<platform name="ios">
    <resource-file src="GoogleService-Info.plist" />    
</platform>
<plugin name="phonegap-plugin-push" spec="2.1.3">
    <variable name="SENDER_ID" value="xxxxxxxxxxxxx" />
</plugin>    

在发送数据包数据时,发送“data”参数和“notification”参数,并包含“content_available”标志,例如...

  $notification = [
                'body'   => $message,
                'title'     => $titlenotification,                    
                "icon" =>  'notification_icon',
                "content_available" => "1", 
  ];


 $data = [
             "title"             =>$titlenotification,  
             "message"           => $message,
             "content_available" => "1",
 ];

 $fields =  [
            'registration_ids'   => $registrationtokens,    
             'notification'      => $notification,        
            'data'               => $data,                         
            "priority"           => "high",
            "content_available"  => true,
 ];

 //send field data like curl_setopt( $ch,CURLOPT_POSTFIELDS, json_encode( $fields ) );

...最后,请务必将您的 google-services.json 添加到根文件夹以及 www 文件夹。否则,当 Phonegap Build 正在处理它时,您将收到错误“A plugin requires google-services.json. The Google Services Plugin cannot function without it”。

如果应用程序已关闭或在后台,这将显示一条通知消息。当您单击通知时,它将打开应用程序并再次显示消息。如果您的应用程序在后台,当您将其带到前台时,也会显示该消息。如果您的应用已关闭并且您没有点击通知消息,那么您将永远不会在您的应用上看到该消息。

【讨论】:

以上是关于当应用程序打开或应用程序处于后台时,Phonegap Firebase 推送通知不会触发事件侦听器的主要内容,如果未能解决你的问题,请参考以下文章

FCM点击应用处于后台状态时如何打开用户指定的活动而不是默认活动

当应用程序未使用或处于后台模式时,React Native 是不是有函数生命周期正在运行?

FCM 点击如何在应用程序处于后台状态时打开用户指定的活动而不是默认活动

当应用程序处于后台或终止状态时如何增加推送通知批处理计数

当应用程序处于后台或设备锁定时,Airplay 停止播放视频流

FIREBASE_MESSAGING:当应用程序处于后台或终止时,onBackgroundMessage 不处理通知