10

I have an iOS app which is live on the app store. I am able to send push notifications to iOS devices which have the app installed, but only when I send them from the Firebase console.

When I try to send push notifications via a cURL request, the response from the server indicates that I was successful but the message isn't received on the device. I have tried this with both multicast and single recipient payloads.

I must be missing something more fundamental, but I can't see it.

Here is my PHP code:

<?php
// API access key from Google API's Console
define( 'API_ACCESS_KEY', 'AI*****4LPGkx8xtDG2tBl*****7KWJfmp1szcA' );
$registrationIds = array( $_GET['id'] );
// prep the bundle
$msg = array
(
    'message'   => 'here is a message. message',
    'title'     => 'This is a title. title'
);
$fields = array
(
    'to'            => "cUxd-iTVVWo:APA*****kQTuqJ5RREKhhlJjm27NCuVfUn5APg3lBFqh-YWjgx*****iOpAQeLB14CzM2YTwIJo_75jzCmbFLKj0_zpKSHvAEbmJz*****BBezGJIng-N4H-cAD6ahY7mQNYZtEJLAIE",
    'data'          => $msg
);

$headers = array
(
    'Authorization: key=' . API_ACCESS_KEY,
    'Content-Type: application/json'
);

$ch = curl_init();
curl_setopt( $ch,CURLOPT_URL, 'https://fcm.googleapis.com/fcm/send' );
curl_setopt( $ch,CURLOPT_POST, true );
curl_setopt( $ch,CURLOPT_HTTPHEADER, $headers );
curl_setopt( $ch,CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch,CURLOPT_SSL_VERIFYPEER, false );
curl_setopt( $ch,CURLOPT_POSTFIELDS, json_encode( $fields ) );
$result = curl_exec($ch );
curl_close( $ch );
echo $result;

Here is the response I get when running this code:

{"multicast_id":5814921248239922706,"success":1,"failure":0,"canonical_ids":0,"results":[{"message_id":"0:1476193002715692%a4ddee3cf9fd7ecd"}]}

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Robbie Lewis
  • 2,844
  • 3
  • 18
  • 29
  • Success: 1, looks like the message is getting delivered successfully. Have you updated the code for iOS 10? – FredLoh Oct 11 '16 at 14:23
  • Yes. The app was successfully converted to Swift 2.3. Notifications are delivered successfully when sent from the Firebase Console – Robbie Lewis Oct 11 '16 at 14:46
  • Are you able to run the app on a test device and see if the message is being delivered? – FredLoh Oct 11 '16 at 14:50
  • Have you tried using `content_available` set to `true` or `priority` set to `high` in your payload? – AL. Oct 11 '16 at 15:20
  • I can't find content_available or priority mentioned anywhere in the documentation. Do you have a link where I can read up on those? I am looking at: https://firebase.google.com/docs/cloud-messaging/server – Robbie Lewis Oct 11 '16 at 16:14
  • @FredLoh I testing on a real iPhone 7 and an iPod touch. – Robbie Lewis Oct 11 '16 at 16:15
  • I was referring to the payload parameters. See [here](https://firebase.google.com/docs/cloud-messaging/http-server-ref). – AL. Oct 12 '16 at 06:55
  • @AL I added content_available and priority. Unfortunately it didn't make any difference. Is there any way I can debug this in firebase to see whether it was processed correctly? – Robbie Lewis Oct 12 '16 at 08:07
  • That's odd. Can you post what your Payload looks like? I think if you have a Google Play account, you can check the status of using the [Diagnostics](https://support.google.com/googleplay/android-developer/answer/2663268?hl=en), but I think your app needs to be at least in Alpha Testing for you to use it. Can you also post your code snippet when receiving the notification? And have you tried using a `notification` payload instead of a `data` payload? – AL. Oct 12 '16 at 09:05
  • 3
    @AL Okay so I realised I should be using `notification` instead of `data`. All I'm looking to do here is cause a standard push notification message in my iOS app, identical to the one that appears when I send a notification from the Firebase admin. Also I should be using `body` instead of `content` for the message contents. My script still isn't working though. Here is my payload: `{"to":"cUxd-iTVVWo:APA...","notification":{"body":"here is a message. message","title":"This is a title. title"}}` – Robbie Lewis Oct 12 '16 at 16:04
  • 1
    Like @AL suggested you need to include priority:high as a sibling to the "to" field. Note though that you should only use priority high when user interaction is required. – Arthur Thompson Oct 12 '16 at 20:49
  • @RobbieLewis Do try out adding the `priority` parameter and set it to `high` as mentioned by Arthur Thompson. If it still doesn't work, try adding in `content_available` and set it to `true`. – AL. Oct 12 '16 at 21:43
  • Thanks to both of you. I decided to go back to basics and tested a simple cURL request over SSH which worked! So now I know it's just a formatting issue in my PHP. – Robbie Lewis Oct 13 '16 at 07:57
  • I'm having the same issue... btw, firebase console seems to show only notifications sent via console rather than those sent through REST API request – bluenowhere Oct 31 '16 at 09:13

4 Answers4

10

There were two issues:

  1. I needed to include a notification section in the payload instead of data
  2. Somehow the payload wasn't being formatted properly by PHP.

In the end I used the PHP function shell_exec() to do a cURL request over SSH instead. This isn't ideal but it got the job done.

Example code:

shell_exec('curl -X POST --header "Authorization: key=<key here>" --header "Content-Type: application/json" https://fcm.googleapis.com/fcm/send -d "{\"to\":\"'.$to.'\",\"priority\":\"high\",\"notification\":{\"body\": \"'.stripslashes($message).'\"}}"');
Robbie Lewis
  • 2,844
  • 3
  • 18
  • 29
6

From the Firebase documentation you have the choice of using either data or notification in the message payload. But when you use data, you have the responsibility of handling the receipt of the notification yourself. In other words it will not be sent straight away to your app client. You handle it in the didReceiveRemoteNotification: for ios and onMessageReceived() in case of Android.

If however you use notification in the payload, firebase will send the message straight away to your client App.

That is why you will not receive the message(in case you used data) even if your curl request tells you it has succeeded in making the request.

ultrasamad
  • 368
  • 4
  • 16
1

Try to add { priority : high }

$fields = array
(
    'to'            => "cUxd-iTVVWo:APA*****kQTuqJ5RREKhhlJjm27NCuVfUn5APg3lBFqh-YWjgx*****iOpAQeLB14CzM2YTwIJo_75jzCmbFLKj0_zpKSHvAEbmJz*****BBezGJIng-N4H-cAD6ahY7mQNYZtEJLAIE",
    'data'          => $msg,
    'priority'      =>'high'
);
Leo Valentim
  • 464
  • 5
  • 19
0

this is what i used :

<?php

//Server keys is now the requirement not the legacy key since its not available

define( 'API_ACCESS_KEY', 'AAAA9....sQ:APA..HKb_Qfz.....q_k4NJonXd...9r-Fof....dJ_ylYLbR....NFz-uQRve.....0GoNISAA......SKx8G_4M...n' );
$messsage = array
(
    'body'   => 'msg',
    'title'     => 'title',
    'key1'  => 'val1'
);
$fields = array
(
    'to'            => "MdS.....Jg:APA91bEhZ........wkZ7rVmt6UmTc4T189M6ie39COvVmqsIA2DEijt_o9lHUGZbSFez......rPqNo4W_Ru............BEGEo6cuWOKu2vasQju",
    'notification'          => $message

);

$headers = array
(
    'Authorization: key=' . API_ACCESS_KEY,
    'Content-Type: application/json'
);

$ch = curl_init();
curl_setopt( $ch,CURLOPT_URL, 'https://fcm.googleapis.com/fcm/send' );
curl_setopt( $ch,CURLOPT_POST, true );
curl_setopt( $ch,CURLOPT_HTTPHEADER, $headers );
curl_setopt( $ch,CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch,CURLOPT_SSL_VERIFYPEER, false );
curl_setopt( $ch,CURLOPT_POSTFIELDS, json_encode( $fields ) );
$result = curl_exec($ch );
curl_close( $ch );
echo $result;
?>

you can add keys and values like example and handle it in your program

iman kazemayni
  • 1,255
  • 1
  • 19
  • 20