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.
P.S. 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.