电容器/离子:处理后台推送通知或应用程序被杀死时的情况

17

大家早上好, 我已经花了几个小时找不到解决方案。

我使用“PushNotifications” Capacitor插件 (https://capacitor.ionicframework.com/docs/apis/push-notifications/)监听从Firebase发送给我的推送通知(包括通知和数据类型),即使在应用程序被杀死或在后台的情况下,通知的监听也运行得非常好,一切都像预期的那样。

问题如下:

当我收到一条通知时,我希望打开应用程序,无论是在后台还是在被杀死的情况下。

  1. 对于应用程序在前台接收到的通知,我可以使用 addListener(eventName: "pushNotificationReceived", callback) 执行自定义代码,在任何情况下都没有问题,因为应用程序是打开的。

  2. 在应用程序在后台接收到通知的情况下,我可以强制应用程序保持 backgroundMode 活动状态 (https://ionicframework.com/docs/native/background-mode) 并在接收到通知时将应用程序带到前台。(虽然我不喜欢这样做,因为会消耗电量)

  3. 如果应用程序被终止,我还没有找到解决方案。

似乎没有办法挂钩自定义代码,使其能够在应用程序在后台接收到推送通知或在应用程序被终止时运行,您是否遇到过这个问题?

谢谢!


有任何关于它的消息吗?我试图在我的移动设备上禁用电池优化,以便我的 Ionic Capacitor 应用程序能够在应用程序被杀死时接收到推送通知。然后,我甚至尝试重新启用优化,惊讶的是,推送通知也能正常工作。看起来很奇怪。希望这不是最终解决方案。 - Adrien SAULNIER
你是如何在Android中获得前台通知的?https://github.com/ionic-team/capacitor/issues/2261 这说明Android没有提供前台通知,只有iOS有。 要获取它们,我们必须使用本地通知...你能解释一下你是如何做到的吗? - Shinichi Kudo
抱歉有点打扰,我很感激您的耐心等待,但是您能在pushNotificationReceived监听器中执行router.navigateByUrl()吗?我看到导航被触发了,但屏幕上没有任何变化,想知道这是否需要解决方案?提前致谢。 - Mad Eddie
4个回答

5

我的解决方案是在 AndroidManifest.xml 中添加FCM_PLUGIN_ACTIVITY操作。

        <activity
        ...
        android:name="com.appname.MainActivity"
        ...>

        ...
        ...
        ...

        <intent-filter>
            <action android:name="FCM_PLUGIN_ACTIVITY" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </activity>

此外在服务器端,您应在推送通知对象中包含该操作:

  const pushNotification = {
  data: {
    ...
  },
  notification: {
    body: body,
    title: title,
    click_action: 'FCM_PLUGIN_ACTIVITY',
  },
};

在Ionic项目中,您可以像下面这样处理 pushNotificationActionPerformed ,然后导航到所需的路由:
  PushNotifications.addListener('pushNotificationActionPerformed',
  (notification: PushNotificationActionPerformed) => {
    console.log('Push action performed: ' + JSON.stringify(notification));
  }
);

处理应用程序在打开状态下接收推送通知时,您应该处理pushNotificationReceived并根据需要自行显示toast。
// the app is open, show your own notification if needed
PushNotifications.addListener('pushNotificationReceived',
  (notification: PushNotification) => {
    console.log('push notification received: ' + JSON.stringify(notification));
  }
);

您在 Android 上前台接收通知吗?使用该实现方式呢? - Shinichi Kudo
你已经收到它们,但必须手动显示它们,检查更新的答案。 - Mozart
在v1 API中,“click_action”似乎不是“notification”内的有效输入。请参考https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages#Notification。 - Kevin
@Kevin https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages#androidnotification - Mozart
没错,这是在“android”部分而不是“notification”部分(虽然安卓自己当然也有通知)。 - Kevin

0

0

我曾经遇到过同样的问题,并通过在AndroidManifest.xml中添加以下行来解决它

<meta-data android:name="com.google.firebase.messaging.default_notification_channel_id" android:value="@string/default_notification_channel_id" />
<service android:name="com.getcapacitor.CapacitorFirebaseMessagingService" android:exported="false"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service>

这个对你还管用吗,@Nour Krimesh? - Richard Gustavsson
这个功能非常好用。主要问题在于,使用 FCM 时可能没有指定通道名称。 - Nikhil Pareek
1
这个答案是针对电容器2、3还是4的? - tobias47n9e

0

我曾经遇到同样的问题。这是关于消息发送技术支持的问题。这里有一个PHP函数,可以将通知从服务器发送到设备上。 "data" 是发送给应用的消息,"notification" 是发送到安卓操作系统的。

function sendGCM($message, $id) {


    $url = 'https://fcm.googleapis.com/fcm/send';

    $fields = array (
            'registration_ids' => array (
                    $id // The device token
            ),
            'data' => array (
                    "message" => $message
            ),
            // After I put "notification", the device started to receive notifications in the background:
            'notification' => array (
                "title" => "App Title Notification",
                "body" => $message
            )
    );
    $fields = json_encode ( $fields );

    $headers = array (
            'Authorization: key=' . "MY_API_Cloud_Messaging_KEY", // App Key from console.firebase.google.com
            'Content-Type: application/json'
    );

    $ch = curl_init ();
    curl_setopt ( $ch, CURLOPT_URL, $url );
    curl_setopt ( $ch, CURLOPT_POST, true );
    curl_setopt ( $ch, CURLOPT_HTTPHEADER, $headers );
    curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, true );
    curl_setopt ( $ch, CURLOPT_POSTFIELDS, $fields );

    $result = curl_exec ( $ch );
    echo $result;
    curl_close ( $ch );

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接