Lorenzo Iovino
Lorenzo Iovino

Reputation: 236

Capacitor/Ionic: Handling push notification in background or when app was killed

Goodmorning everyone, I haven't been able to find a solution for several hours now.

I use the "PushNotifications" Capacitor plugin (https://capacitor.ionicframework.com/docs/apis/push-notifications/) to listen to push notifications that come to me from firebase (both notification and data type), the listening of notifications happens very well and everything behaves as expected even in cases of app killed or in the background.

The problem is the following:

I want to open the app when I receive a notification, if it is in the background or if it has been killed.

  1. In the case of notification received when the app is in the foreground, I can run custom code using addListener(eventName: "pushNotificationReceived", callback) and in any case I have no problems because the app is open.

  2. In case of notification received when the app is in the background, I can force the app to keep the backgroundMode active (https://ionicframework.com/docs/native/background-mode) and bring the app to the foreground upon receiving a notification. (although I don't really like it because it's battery consuming)

  3. In case of app killed, I have not found solutions to the problem.

It seems that there is no way to hook custom code to be able to run when a push notification arrives when it is received in the background or with the app killed, have you ever had this problem?

Thank you!

Upvotes: 19

Views: 12163

Answers (4)

Nour Krimesh
Nour Krimesh

Reputation: 1

I had the same issue and fixed it with the following lines in AndroidManifest.xml

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

Change "yourapp_notifications_channel_name" with a name as you want but you have to add it to your capacitor PushNotification as the following:

if (this.platform.is('android')) {
  const channel: Channel = {
     id: 'yourapp_notifications_channel',
     name: 'yourapp_notifications_channel',
     sound: 'yourapp_notification_sound_file_name',
     importance: 5,
     visibility: 1,
     vibration: true
   };
   await PushNotifications.createChannel(channel);
}
PushNotifications.addListener('registration', async (fcmToken: Token) => {
/// your notificaiton logic
}```

Upvotes: 0

Yoshi Varela
Yoshi Varela

Reputation: 26

I was having the same problem. It was a technical underpinning of how messages are sent. Here is a PHP function that sends notifications from the server to the device. "data" is message sent to app, "notification" is sent to android OS.

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 );

}

Upvotes: 0

E.ws
E.ws

Reputation: 643

For us background-notifications (even after App was killed) also worked if we additionally installed the FCM Plugin (https://github.com/capacitor-community/fcm), which we need for iOS.

Upvotes: 0

Mozart
Mozart

Reputation: 2302

My solution was to add: FCM_PLUGIN_ACTIVITY action to AndroidManifest.xml

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

        ...
        ...
        ...

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

In addition on the server you should include the action in your push notification object:

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

And inside you ionic project you handle pushNotificationActionPerformed like below and navigate to the desired route:

  PushNotifications.addListener('pushNotificationActionPerformed',
  (notification: PushNotificationActionPerformed) => {
    console.log('Push action performed: ' + JSON.stringify(notification));
  }
);

To handle receiving push notifications in when the app is open you should handle pushNotificationReceived and show a toast yourself if needed.

// the app is open, show your own notification if needed
PushNotifications.addListener('pushNotificationReceived',
  (notification: PushNotification) => {
    console.log('push notification received: ' + JSON.stringify(notification));
  }
);

Upvotes: 6

Related Questions