Cordova Firebase background push notifications not working in iOS13 and XCode 11?

  |   By  |  0 Comments

What a pain! Push notifications work when the app is in the foreground, but had stopped when the app is in the background. I’d update my app too!

I am using cordova-plugin-firebase, which is being kept upto date more than  cordova-plugin-fcm

There are 2 reason for this that I have found!

1) XCode 11 doesn’t remember some of the previous capabilities. It remembered push notifications, but not background modes!

You need to make sure BackgroundModes is added (little + to the left of Capability) and then check  Remote Notifications

Background Push modes

2) The POST to Firebase needs adding too with some APNS headers

Here is my PHP code with the extra APNS headers. All learned from https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages  and https://onesignal.com/blog/ios-13-introduces-4-breaking-changes-to-notifications/

$url = 'https://fcm.googleapis.com/fcm/send';
$headers = array('Authorization: key=' . $api_key,'Content-Type: application/json');
$data=array("notification"=>array("title"=>"Church App",
				 "body"=>$title." - ".$post->post_title,
				"sound"=>"default",
				 "icon"=>"fcm_push_icon",
				"content_available"=> 1,
                                 'apnsPushType'=>'alert'
													 ),
                                  "apns"=> array(
                                            'headers'=> array( 
                                                        'apns-push-type'=> 'alert',
                                                        "apns-priority"=>5,
                                                        "apns-topic"=>"com.churchadminplugin.wpchurch"
                                            ),
                                            "payload"=>array("alert"=>array("title"=>"Church App","body"=>$title." - ".$post->post_title),
                                                             "aps"=>array( "content-available"=>1),
                                                             "sound"=>"default","content-available"=>1
                                                            ),
                                    
                                ),
								"data"=>array(  "notification_foreground"=>TRUE,
                                                "notification_body" => $title." - ".$post->post_title,
                                                "notification_title"=> "Church App",
                                              "notification_android_priority"=>1,
                                              "notification_ios_sound"=>"default",
                                              "sound"=>"default",
                                                "title"=>"Church App",
											  "body"=>$title." - ".$post->post_title,
											  "type"=>"message",
											  "senderName"=>$username,
												"timestamp"=>mysql2date(get_option('date_format').' '.get_option('time_format'),date("Y-m-d H:i:s"))
										),
								"to"=>"/topics/church".$appID,
								"priority"=>"high"
								);
$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, json_encode($data) );

And then…. Android. Ouch.

I have been using cordova-plugin-firebase which is now no good – you need to use a fork…

cordova-plugin-firebasex

Then you need to add cordova-plugin-androidx and cordova-plugin-androidx-adapter

But not before youhave updated Cordova to v9.0.0 and Cordova Android>=8.0 Aaaagh.

And then made some changes in your code from cordova-plugin-firebase to cordova-plugin-firebasex

  • onNotificationOpen() renamed to onMessageReceived()
    • tap parameter is only set when user taps on a notification (not when a message is received from FCM)
    • tap=foreground|background instead of tap=true|false
  • hasPermission() receives argument as a boolean (rather than an object with isEnabled key)
    • e.g. window.FirebasePlugin.hasPermission(function(hasPermission){ console.log("Permission is " + (hasPermission ? "granted" : "denied")); });

Then you need some notification icons – single colour transparent pngs

Place them in the folder and update config.xml like so

<platform name="android">
    <resource-file src="res/android/drawable-mdpi/notification_icon.png" target="app/src/main/res/drawable-mdpi/notification_icon.png" />
    <resource-file src="res/android/drawable-hdpi/notification_icon.png" target="app/src/main/res/drawable-hdpi/notification_icon.png" />
    <resource-file src="res/android/drawable-xhdpi/notification_icon.png" target="app/src/main/res/drawable-xhdpi/notification_icon.png" />
    <resource-file src="res/android/drawable-xxhdpi/notification_icon.png" target="app/src/main/res/drawable-xxhdpi/notification_icon.png" />
    <resource-file src="res/android/drawable-xxxhdpi/notification_icon.png" target="app/src/main/res/drawable-xxxhdpi/notification_icon.png" />
</platform>

And also add this

<platform name="android">
    <config-file target="AndroidManifest.xml" parent="/manifest/application">
        <meta-data android:name="com.google.firebase.messaging.default_notification_icon" android:resource="@drawable/notification_icon" />
    </config-file>
</platform>

Then it all worked first time. Unbelievable!

But all this also means some more changes for iOS in a moment!!!

FirebaseX uses cocoapods

so you need to install that

sudo gem install cocoapods

Then after a cup of tea or two…

Check it installed with

pod --version

Go to to the platforms/ios directory and

pod repo update

pod install

After another tea or beer, you can build ios and that works finally with sounds too! Hurrah.

name

ABOUT THE AUTHOR - ANDY MOYLE

Andy Moyle is a church leader and web developer. His biggest project is the Church Admin WordPress plugin and app. He also runs, mainly so he can eat pizza.