2

I'm trying to write an application to receive notifications via Firebase Cloud Messaging. It initially worked when I tried to send the message via Firebase console but then the moment I tried doing the same using php webservice, in response, it showed success but I neither received the message nor am I able to get any more notifications via firebase console. Please help

My server side code:

MainActivity.java

package com.example.mojojojo.firebasenotifications;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.EditText;

import com.google.firebase.iid.FirebaseInstanceId;

public class MainActivity extends AppCompatActivity {

    private EditText etToken;
    private SharedPreferences sp;
    private SharedPreferences.Editor edit;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        etToken=(EditText)findViewById(R.id.etToken);

        sp=getSharedPreferences("pref",MODE_PRIVATE);
        edit=sp.edit();

        etToken.setText(FirebaseInstanceId.getInstance().getToken());
        BroadcastReceiver tokenReceiver=new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                String token=intent.getExtras().getString("token");
                if(token!=null){
                    etToken.setText(token);
                }
            }
        };
        registerReceiver(tokenReceiver,new IntentFilter("TOKEN_GENERATED"));
    }
}

Messaging service

package com.example.mojojojo.firebasenotifications;

import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;
import android.util.Log;

import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;

public class MessagingService extends FirebaseMessagingService {

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);
        String msg=remoteMessage.getNotification().getBody();
        sendNotification(msg);
        Log.i("/>/>",msg);
    }
    private void sendNotification(String messageBody) {
        Intent intent = new Intent(this, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 , intent,
                PendingIntent.FLAG_ONE_SHOT);

        Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentTitle("FCM Message")
                .setContentText(messageBody)
                .setAutoCancel(true)
                .setSound(defaultSoundUri)
                .setContentIntent(pendingIntent);

        NotificationManager notificationManager =
                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        notificationManager.notify(0 , notificationBuilder.build());
    }
}

Token Service

package com.example.mojojojo.firebasenotifications;

import android.app.Service;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.IBinder;

import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.iid.FirebaseInstanceIdService;

public class TokenService extends FirebaseInstanceIdService {
    private SharedPreferences sp;
    private SharedPreferences.Editor edit;

    @Override
    public void onTokenRefresh() {
        super.onTokenRefresh();

        sp=getSharedPreferences("pref",MODE_PRIVATE);
        edit=sp.edit();

        String token= FirebaseInstanceId.getInstance().getToken();
        edit.putString("token",token);

        Intent tokenIntent=new Intent("TOKEN_GENERATED");
        tokenIntent.putExtra("token",token);
        sendBroadcast(tokenIntent);
    }
}

Manifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.mojojojo.firebasenotifications">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service
            android:name=".MessagingService"
            android:enabled="false"
            android:exported="false" >
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT"/>
            </intent-filter>
        </service>

        <service
            android:name=".TokenService">
            <intent-filter>
                <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
            </intent-filter>
        </service>
    </application>

</manifest>

and my php code is as follows (I've removed the server Key in the code)

<?php
define( 'API_ACCESS_KEY', 'YOUR-API-ACCESS-KEY-GOES-HERE' );
$registrationIds = array( $_GET['id'] );
// prep the bundle
$msg = array
(
    'message'   => 'hi',
    'title'     => 'This is a title. title',
    'subtitle'  => 'This is a subtitle. subtitle',
    'tickerText'    => 'Ticker text here...Ticker text here...Ticker text here',
    'vibrate'   => 1,
    'sound'     => 1,
    'largeIcon' => 'large_icon',
    'smallIcon' => 'small_icon'
);
$fields = array
(
    'registration_ids'  => $registrationIds,
    'data'          => $msg
);

$headers = array
(
    'Authorization: key=' . 'xxxxxxxxxxxxxxxxxxxxx',
    '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;
?>
Pinaki Acharya
  • 339
  • 3
  • 11

5 Answers5

4

This php code finally worked for me.

<?php 
function send_notification ($tokens)
{

    $url = 'https://fcm.googleapis.com/fcm/send';
    $priority="high";
    $notification= array('title' => 'Some title','body' => 'hi' );

    $fields = array(
         'registration_ids' => $tokens,
         'notification' => $notification

        );


    $headers = array(
        'Authorization:key=xxxxxxxxxxxxx',
        '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_SSL_VERIFYHOST, 0);  
   curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
   curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
    // echo json_encode($fields);
   $result = curl_exec($ch);           
   echo curl_error($ch);
   if ($result === FALSE) {
       die('Curl failed: ' . curl_error($ch));
   }
   curl_close($ch);
   return $result;
}
$tokens = array('RECEIVER-TOKEN-1'
    ,'RECEIVER_TOKEN-2');

  $message_status = send_notification($tokens);
  echo $message_status;
?>

P.S: I've hard coded the receiver tokens as of now (for testing purposes)

Shahzad Barkati
  • 2,532
  • 6
  • 25
  • 33
Pinaki Acharya
  • 339
  • 3
  • 11
1

You have not posted what you get as result message after you echo $result. So for now after going through your code, I found:

String msg=remoteMessage.getNotification().getBody();

This line is causing problem. You should instead use it like this:

remoteMessage.getData().get("message")
remoteMessage.getData().get("title")
remoteMessage.getData().get("subtitle")

and so on..

For further clearance, we use:

remoteMessage.getNotification().getBody() when we have notification object in the JSON that we sent to fcm server. Which in your case is not there, instead you have data object and for that we use :

remoteMessage.getData().get("key_name")

rusted brain
  • 1,052
  • 10
  • 23
  • This isn't my prime concern(and problem). My problem is that I tried writing the code twice. With both the applications that I tried to write, I was initially getting notifications using firebase console and then I tried executing the php webservice, got success but didn't get notification and then I stopped getting notifications from the firebase console as well – Pinaki Acharya Jun 09 '16 at 07:25
  • did you try to `Log` anything in `onMessageReceived()`? – rusted brain Jun 09 '16 at 07:28
  • What did you get in the log? Please care to post it in the question. – rusted brain Jun 09 '16 at 07:36
1

try this:

<?php 

function send_notification ($tokens, $message)
{
    $url = 'https://fcm.googleapis.com/fcm/send';
    $fields = array(
         'registration_ids' => $tokens,
         'data' => $message
        );

    $headers = array(
        'Authorization:key = YOUR_KEY ',
        '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_SSL_VERIFYHOST, 0);  
   curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
   curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
   $result = curl_exec($ch);           
   if ($result === FALSE) {
       die('Curl failed: ' . curl_error($ch));
   }
   curl_close($ch);
   return $result;
}


$conn = mysqli_connect("localhost","root","","fcm");

$sql = " Select Token From users";

$result = mysqli_query($conn,$sql);
$tokens = array();

if(mysqli_num_rows($result) > 0 ){

    while ($row = mysqli_fetch_assoc($result)) {
        $tokens[] = $row["Token"];
    }
}

mysqli_close($conn);

   $message = array("message" => " FCM PUSH NOTIFICATION TEST MESSAGE");
   $message_status = send_notification($tokens, $message);
   echo $message_status;

?>
Shahzad Barkati
  • 2,532
  • 6
  • 25
  • 33
FireUser
  • 173
  • 1
  • 3
  • 13
  • 1
    Is it working for you? Also, instead of fetching data values from table, if I wish to pass just **one** registration token via a POST request, how am I supposed to do it? – Pinaki Acharya Jun 09 '16 at 12:11
  • Yes, its working for me. Yes, to pass one registration token via post request u will change code a little. Tomorrow, i will show u me code. – FireUser Jun 09 '16 at 13:35
  • @PinakiAcharya If you wish to pass just one registration token you can use `to => your_token` instead of `registration_ids` . – rusted brain Jun 10 '16 at 06:02
  • Thanks so much. @rustedbrain and fire user, the to thing+adding a body worked out for me. I'm posting the php code in the answer below which finally worked for me. – Pinaki Acharya Jun 10 '16 at 10:11
  • 1
    One thing you should also keep in mind that if you want to send notifications to all users of the app you need not save the registration token in the database and loop through every one of them, FCM has `topics` you can subscribe user to the topic once and then you can send notifications to that topic and everyone who has subscribed will receive notification. To do that in `to` field instead of token you have to write `/topic/TOPIC_NAME`. see this link for more info https://firebase.google.com/docs/cloud-messaging/topic-messaging – rusted brain Jun 10 '16 at 11:39
0
    <?php 

    function send_notification ($tokens, $message)
    {
        $url = 'https://fcm.googleapis.com/fcm/send';
        $fields = array(
             'registration_ids' => $tokens,
             'data' => $message
            );

        $headers = array(
            'Authorization:key = your token ',
            '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_SSL_VERIFYHOST, 0);  
       curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
       curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
       $result = curl_exec($ch);           
       if ($result === FALSE) {
           die('Curl failed: ' . curl_error($ch));
       }
       curl_close($ch);
       return $result;
    }

//Checking post request 
if($_SERVER['REQUEST_METHOD']=='POST'){

    //Connection to database

    $conn = mysqli_connect("localhost","root","","bbdd");

     //Geting email and message from the request 

    $email = $_POST['Email'];
    $msg = $_POST['message'];

    //Getting the firebase id of the person selected to send notification
    $sql = "SELECT * FROM users WHERE email = '$email'";


    $result = mysqli_query($conn,$sql);
    $tokens = array();

    if(mysqli_num_rows($result) > 0 ){

        while ($row = mysqli_fetch_assoc($result)) {
            $tokens[] = $row["Token"];
        }
    }

    mysqli_close($conn);

    $message = array("message" =>"$msg");
    $message_status = send_notification($tokens, $message);
    echo $message_status;

    //redirecting back to the sendnotification page 
    header('Location: sendPushNotification.php?success');
}else{
    header('Location: sendPushNotification.php');
}



 ?>

to one user

FireUser
  • 173
  • 1
  • 3
  • 13
0

This worked for me ... the FCM endpoint is maybe not that reliable . Try this

  $url = 'https://gcm-http.googleapis.com/gcm/send';

Just this dont change anything else. Also this endpoint will continue to live , google has no plans to deprecate GCM as mentioned in their Developer videos.

One more thing.. is there a delay or you are not getting the message at all .If there is a delay that maybe due to TCP timeout problem . Try this and let me know . Good Luck !!

Sarthak Mishra
  • 1,033
  • 1
  • 11
  • 27