I creating app using CapacitorJS and Svelte with php Backend, my problem is I fail to implement push notification while app is backgrounded (or killed)
here my Android manifest
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"><application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"><activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode" android:name=".MainActivity" android:label="@string/title_activity_main" android:theme="@style/AppTheme.NoActionBarLaunch" android:launchMode="singleTask" android:exported="true"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter><intent-filter><action android:name="FCM_PLUGIN_ACTIVITY" /><category android:name="android.intent.category.DEFAULT" /></intent-filter></activity><provider android:name="androidx.core.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true"><meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths"></meta-data></provider><service android:name=".MyFirebaseMessagingService" android:exported="true"><intent-filter><action android:name="com.google.firebase.MESSAGING_EVENT" /></intent-filter></service><receiver android:name="com.google.firebase.iid.FirebaseInstanceIdReceiver" android:exported="true" android:permission="com.google.android.c2dm.permission.SEND"><intent-filter><action android:name="com.google.android.c2dm.intent.RECEIVE" /><category android:name="${applicationId}" /></intent-filter></receiver></application><!-- Permissions --><uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /><uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /><uses-permission android:name="android.permission.POST_NOTIFICATIONS" /><uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" /></manifest>
here my custom java class extending firebaseCloudMessaging
package com.appapp.omi;import android.app.NotificationChannel;import android.app.NotificationManager;import android.content.pm.PackageManager;import android.os.Build;import android.util.Log;import androidx.core.app.ActivityCompat;import androidx.core.app.NotificationCompat;import androidx.core.app.NotificationManagerCompat;import com.capacitorjs.plugins.pushnotifications.PushNotificationsPlugin;import com.getcapacitor.BridgeActivity;import com.getcapacitor.JSObject;import com.getcapacitor.Plugin;import com.getcapacitor.PluginHandle;import com.google.firebase.messaging.FirebaseMessagingService;import com.google.firebase.messaging.RemoteMessage;import com.getcapacitor.Bridge;import com.getcapacitor.PluginCall;import com.getcapacitor.PluginManager;public class MyFirebaseMessagingService extends FirebaseMessagingService { private static final String TAG = "PushNotificationService"; private static final String CHANNEL_ID = "default_channel"; @Override public void onMessageReceived(RemoteMessage remoteMessage) { super.onMessageReceived(remoteMessage); String title = "Default Title"; String body = "Default Body"; JSObject dataObj = new JSObject(); if (remoteMessage.getNotification() != null) { title = remoteMessage.getNotification().getTitle(); body = remoteMessage.getNotification().getBody(); } else if (remoteMessage.getData().size() > 0) { // Handle custom data payload title = remoteMessage.getData().get("title"); body = remoteMessage.getData().get("body"); } if (MainActivity.bridge != null) { PluginHandle pushPluginHandle = MainActivity.bridge.getPlugin("PushNotifications"); if (pushPluginHandle != null) { PushNotificationsPlugin pushPlugin = (PushNotificationsPlugin) pushPluginHandle.getInstance(); pushPlugin.fireNotification(remoteMessage); }// MainActivity.bridge.triggerJSEvent("pushNotificationReceived", jsonString); // MainActivity.bridge.triggerWindowJSEvent("pushNotificationReceived", data.toString()); } else { Log.e("MyFirebaseService", "Bridge not initialized"); } // Show notification NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID) .setContentTitle(title) .setContentText(body) .setSmallIcon(R.mipmap.ic_launcher) // Replace with your app's notification icon .setPriority(NotificationCompat.PRIORITY_HIGH); NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this); if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) { // TODO: Consider calling // ActivityCompat#requestPermissions // here to request the missing permissions, and then overriding // public void onRequestPermissionsResult(int requestCode, String[] permissions, // int[] grantResults) // to handle the case where the user grants the permission. See the documentation // for ActivityCompat#requestPermissions for more details. return; } notificationManager.notify(0, builder.build()); }}
here my implementation pushnotif in capacitorjs
export async function registerPushNotifications() { try { PushNotifications.requestPermissions().then((status) => { console.log({status}) if (status.receive === 'granted') { PushNotifications.addListener("pushNotificationReceived", (notification) => { console.log() // console.log({notification: JSON.parse(notification)}); addGNotif(notification); }, ); // Listener for errors PushNotifications.addListener("registrationError", (error) => { console.error("Push registration error:", error); }); PushNotifications.addListener('pushNotificationActionPerformed', (action) => { console.log(action) alert("clicked") }); FCM.getToken() .then((r) => { saveToken(r.token); }) .catch((err) => console.log(err)); } }) } catch (error) { console.error('Push notification setup failed:', error); }}
here my backend php
use Kreait\Firebase\Factory;use Kreait\Firebase\Messaging\CloudMessage;function appapp_sendPushNotification($registrationTokens, $title, $body, $data = []) { // Initialize Firebase $factory = (new Factory) ->withServiceAccount(ABSPATH.DIRECTORY_SEPARATOR.'wp-content'.DIRECTORY_SEPARATOR.'uploads'.DIRECTORY_SEPARATOR.'firebase-service-account.json'); // Optional if using Realtime Database $messaging = $factory->createMessaging(); // Create the message $message = CloudMessage::new() ->withNotification(['title' => $title,'body' => $body, ])->withTarget('token', $registrationTokens)->withHighestPossiblePriority()->withAndroidConfig(array('priority' => 'high', 'notification' => ['title' => $title,'body' => $body, ], 'data' => $data)); try { $response = $messaging->send($message); // $response = $messaging->sendMulticast($message, $registrationTokens); error_log(json_encode($response)); return $response; } catch (\Throwable $e) { error_log($e->getMessage()); return $e->getMessage(); }}
my capacitor version is v.6
"@capacitor/android": "^6.1.2","@capacitor/app": "^6.0.2","@capacitor/cli": "^6.1.2","@capacitor/core": "^6.1.2","@capacitor/inappbrowser": "^1.0.2","@capacitor/keyboard": "^6.0.3","@capacitor/local-notifications": "^6.1.1","@capacitor/preferences": "^6.0.2","@capacitor/push-notifications": "^6.0.3",
my capacitor config
{"appId": "com.appapp.omi","appName": "OMI App","webDir": "dist/client","allowNavigation": ["wa.me", "api.whatsapp.com", "orbitalmedika.co.id"],"plugins": {"PushNotifications": {"presentationOptions": ["badge", "sound", "alert"] },"Keyboard": {"resize": "none" } }}
while app in foreground, notification is received but not while in background