简体   繁体   中英

Migrate from GCM to FCM

Recently I`ve migrated from GCM to FCM and past few days I'm struggling to make it work.

Android Apps are receiving notifications from google firebase console but they don't from php server.

This is my PHP server side code:

<?php



define("GOOGLE_API_KEY", Setting::get('browser_key') ? Setting::get('browser_key') : "");


class GCM {

function __construct() {

}


public function send_notification($registatoin_ids, $message) {

    Log::info("GOOGLE_API_KEY".GOOGLE_API_KEY);

    include_once 'const.php';
    $url = 'https://fcm.googleapis.com/fcm/send';

    $fields = array(
        'registration_ids' => $registatoin_ids,
        'data' => $message,
    );

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

    Log::info('***** PUSH MESSAGE ******'.print_r(json_encode($fields),true));

    $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_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));

    $result = curl_exec($ch);

    Log::info(print_r($result,true));

    if ($result === FALSE) {
        //die('Curl failed: ' . curl_error($ch));
        Log::error('Curl failed: ' . curl_error($ch));
    }
    else{
        //echo $result;
        Log::error($result);
    }

    // Close connection
    /*curl_close($ch);
     echo $result/*."\n\n".json_encode($fields); */

}

}
?>

This is my const.php

<?php

    define('TEAM','team');

    define('MESSAGE' , 'message');

?>

This is my firebase messanging code:

public class MessagingService extends FirebaseMessagingService {

private static final String TAG = "FCM Message";

public MessagingService() {
    super();
}

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    super.onMessageReceived(remoteMessage);

    sendNotification(remoteMessage.getNotification().getBody());

    Log.d(TAG, "From: " + remoteMessage.getFrom());
    Log.d(TAG, "Notification Message Body: " + remoteMessage.getNotification());
}

private void sendNotification(String body) {


    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);
    notificationBuilder.setContentTitle("Codegama");
    notificationBuilder.setContentText(body);
    notificationBuilder.setAutoCancel(true);
    notificationBuilder.setSound(defaultSoundUri);
    notificationBuilder.setContentIntent(pendingIntent);

    NotificationManager notificationManager =  (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    notificationManager.notify(0,notificationBuilder.build());




}
}

and this is the error I keep getting in logcat android studio :

 java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.google.firebase.messaging.RemoteMessage$Notification.getBody()' on a null object reference
    at hr.trazim.client.services.MessagingService.onMessageReceived(MessagingService.java:32)
    at com.google.firebase.messaging.FirebaseMessagingService.zzd(Unknown Source:60)
    at com.google.firebase.iid.zzg.run(Unknown Source:4)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
    at com.google.android.gms.common.util.concurrent.zza.run(Unknown Source:6)
    at java.lang.Thread.run(Thread.java:919)

2020-01-07 12:08:11.092 1732-29214/? E/ResolverController: No valid NAT64 prefix (101, /0)

I was reading a lot on stackoverflow subjects like this and I couldn't find proper fix/solution. I hope this fix gonna help other devs like me find suitable answers without lossing too much time as I did.

PS In case you need my token I haven't migrated it yet but it's working here is the code :

public class InstanceIDService extends FirebaseInstanceIdService {

@Override
public void onTokenRefresh() {
    super.onTokenRefresh();
    String refreshedToken = FirebaseInstanceId.getInstance().getToken();
    Log.e("FCMToken", refreshedToken);
    saveDeviceToken(refreshedToken);
}

private void saveDeviceToken(String token) {
    UserDataSource.getDataInstance().putDeviceToken(token);
}

}

Thanks in advance.

You are getting wrong data. it should be like this. or try to print data first then get from array.

sendNotification(remoteMessage.getData().get("message"));
Log.d("Push data", remoteMessage.getData().toString());

try to use this :

@TargetApi(Build.VERSION_CODES.O)
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)

public void show_Notification(){

Intent intent=new Intent(getApplicationContext(),MainActivity.class);
String CHANNEL_ID="MYCHANNEL";
NotificationChannel notificationChannel=new NotificationChannel(CHANNEL_ID,"name",NotificationManager.IMPORTANCE_LOW);
PendingIntent pendingIntent=PendingIntent.getActivity(getApplicationContext(),1,intent,0);
Notification notification=new Notification.Builder(getApplicationContext(),CHANNEL_ID)
        .setContentText("Heading")
        .setContentTitle("subheading")
        .setContentIntent(pendingIntent)
        .addAction(android.R.drawable.sym_action_chat,"Title",pendingIntent)
        .setChannelId(CHANNEL_ID)
        .setSmallIcon(android.R.drawable.sym_action_chat)
        .build();

NotificationManager notificationManager=(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    notificationManager.createNotificationChannel(notificationChannel);
notificationManager.notify(1,notification);


 }

To send Firebase push notification from php server you can use this code.

<?php

function sendMessage($data, $target, $serverKey){
    //FCM api URL
    $rsp = [];
    $url = 'https://fcm.googleapis.com/fcm/send';
    //api_key available in Firebase Console -> Project Settings -> CLOUD MESSAGING -> Server key
    $server_key = $serverKey;
    $fields = array();
    $fields['data'] = $data;
    if(is_array($target)){
            $fields['registration_ids'] = $target;
        }else{
            $fields['to'] = $target;
    }
    //header with content_type api key
    $headers = array(
        'Content-Type:application/json',
        'Authorization:key='.$server_key
    );

    $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('FCM Send Error: ' . curl_error($ch));
    }
    curl_close($ch);

    //print_r($result);
    return $result;
}

And if you want to update your android code you can follow this post: Firebase push notification

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM