简体   繁体   English

从 GCM 迁移到 FCM

[英]Migrate from GCM to FCM

Recently I`ve migrated from GCM to FCM and past few days I'm struggling to make it work.最近我从 GCM 迁移到 FCM,过去几天我正在努力使它工作。

Android Apps are receiving notifications from google firebase console but they don't from php server. Android 应用程序正在从 google firebase 控制台接收通知,但它们不会从 php 服务器接收通知。

This is my PHP server side code:这是我的 PHP 服务器端代码:

<?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这是我的 const.php

<?php

    define('TEAM','team');

    define('MESSAGE' , 'message');

?>

This is my firebase messanging code:这是我的 firebase 消息传递代码:

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 :这是我在 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/? 2020-01-07 12:08:11.092 1732-29214/? E/ResolverController: No valid NAT64 prefix (101, /0) E/ResolverController: 没有有效的 NAT64 前缀 (101, /0)

I was reading a lot on stackoverflow subjects like this and I couldn't find proper fix/solution.我在这样的stackoverflow主题上阅读了很多,但找不到合适的修复/解决方案。 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 : PS如果您需要我的令牌,我还没有迁移它,但它在这里工作的是代码:

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 服务器发送Firebase 推送通知,您可以使用此代码。

<?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如果你想更新你的 android 代码,你可以关注这篇文章: Firebase 推送通知

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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