I am trying to implement FCM in my app. Right now, I am able to receive messages when i send them from firebase app console. But when i try to send messages from my server, the message is not getting delivered to the phone. However, I am getting a success status after sending message from the server and it shows delivered to 1 device. Any help would be appreciated.
Thanks.
Manifest File:
</application>
<service
android:name=".FirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
<service
android:name=".FirebaseInstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
</manifest>
Build.gradle app:
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:24.0.0'
compile 'com.android.support:design:24.0.0'
compile 'com.squareup.okhttp3:okhttp:3.2.0'
compile 'com.google.firebase:firebase-messaging:9.0.2'
}
apply plugin: 'com.google.gms.google-services'
Build.gradle project:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.1.2'
classpath 'com.google.gms:google-services:3.0.0'
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
Code:
public class FirebaseMessagingService extends com.google.firebase.messaging.FirebaseMessagingService {
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
ShowNotification(remoteMessage.getData().get("message"));
}
private void ShowNotification(String message) {
Intent i = new Intent(this,MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingintent = PendingIntent.getActivity(this,0,i,PendingIntent.FLAG_UPDATE_CURRENT);
android.support.v4.app.NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setAutoCancel(true)
.setContentTitle("FCM Test")
.setContentText(message)
.setSmallIcon(R.drawable.common_google_signin_btn_icon_dark)
.setContentIntent(pendingintent);
NotificationManagerCompat manager =(NotificationManagerCompat) getSystemService(NOTIFICATION_SERVICE);
manager.notify(0,builder.build());
}
}
public class FirebaseInstanceIDService extends FirebaseInstanceIdService {
#Override
public void onTokenRefresh() {
String token = FirebaseInstanceId.getInstance().getToken();
System.out.println("TOKEN " + token);
}
}
Server Side Code:
function send_notification ($tokens, $message)
{
$url = 'https://fcm.googleapis.com/fcm/send';
$fields = array(
'registration_ids' => $tokens,
'data' => $message
);
$headers = array(
'Authorization: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;
}
$tokens = array();
$tokens[] = "***********************************************";
$message = array("message" => " DEEPAK PUSH TEST MESSAGE");
$message_status = send_notification($tokens, $message);
echo $message_status;
I was able to fix the issue. The format in which I was generating json, was wrong. I didnt put the payload under notification tag. Post that change it started working. Thanks a lot guys, for all your suggestions.
Related
i'm using FCM and follow instructions on firebase site but notifications not working when app in background
i already sync gradle library and download json file and sync done but not notifications recieved when app in background
app gradle
dependencies {
///////
}
apply plugin: 'com.google.gms.google-services'
dependencies {
classpath 'com.android.tools.build:gradle:3.5.1'
classpath 'com.google.gms:google-services:4.3.2'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
You have to add
classpath 'com.android.tools.build:gradle:3.5.1'
classpath'com.google.gms:google-services:4.3.2'
in project gradle and google plugin in app gradle file.
Then add the following dependencies:
implementation 'com.google.firebase:firebase-core:17.2.0'
implementation 'com.google.firebase:firebase-messaging:19.0.0'
You need to create a service of FCM to recieve notifications.
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private NotificationManager notificationManager;
private static final String ADMIN_CHANNEL_ID = "CHANNEL_ID";
#Override
public void onNewToken(String s) {
super.onNewToken( s );
}
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived( remoteMessage );
Map<String, String> data = remoteMessage.getData();
String body = data.get("body");
String title = data.get("title");
String image = data.get("image");
notificationManager = (NotificationManager) getSystemService( Context.NOTIFICATION_SERVICE);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
setupChannels( title, body );
}
Log.d( "Notification", "onMessageReceived: " + image);
Intent notificationIntent = new Intent(this, NotificationActivity.class);
notificationIntent.setFlags( Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP );
PendingIntent pendingIntent = PendingIntent.getService( this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT );
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder( this, ADMIN_CHANNEL_ID )
.setSmallIcon( R.drawable.ic_launcher_background )
.setContentTitle( remoteMessage.getNotification( ).getTitle( ) )
.setContentText( remoteMessage.getNotification( ).getBody( ) )
.setContentIntent( pendingIntent );
NotificationManager notificationManager = (NotificationManager) getSystemService( Context.NOTIFICATION_SERVICE );
notificationManager.notify( 0, notificationBuilder.build( ) );
}
#RequiresApi(api = Build.VERSION_CODES.O)
private void setupChannels(String adminChannelName, String adminChannelDescription) {
NotificationChannel adminChannel;
adminChannel = new NotificationChannel( ADMIN_CHANNEL_ID, adminChannelName, NotificationManager.IMPORTANCE_LOW );
adminChannel.setDescription( adminChannelDescription );
adminChannel.enableLights( true );
adminChannel.setLightColor( Color.RED );
adminChannel.enableVibration( true );
if (notificationManager != null) {
notificationManager.createNotificationChannel( adminChannel );
}
}
}
And add this code to your manifest:
<service
android:name=".MyFirebaseMessagingService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
There are several steps for achieving the notification when application is in background.
You need to use POST parameter in Android FCM service.
You need to code down the thing inside onMessageReceived() from FCM dependencies.
https://firebase.google.com/docs/cloud-messaging/android/receive#handling_messages
because i just send notification without message body
i tried solution i just found that i forget this gradle library
implementation 'com.google.firebase:firebase-messaging:20.0.0'
I have implemented firebase cloud messaging in my Android app. When I send notification from backed or Firebase console onMessageReceived() is triggered twice and generates two notifications on device. I've tried to search on internet but no results found for this problem
here is my code,
MyFirebaseNotificationService.java
public class MyFirebaseNotificationService extends FirebaseMessagingService {
#Override
public void onNewToken(String s) {
super.onNewToken(s);
MyApp.getInstance().saveFCMToken(s);
}
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
int notificationId = new Random().nextInt(60000);
String customerId = "";
Log.e("NOTIF", "" + remoteMessage.getData());
Intent notificationIntent = new Intent(this, SplashActivity.class);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK);
notificationIntent.setAction(Long.toString(System.currentTimeMillis()));
final PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, "100")
.setSmallIcon(R.drawable.ic_app_icon)
.setColorized(true)
.setPriority(PRIORITY_HIGH)
.setColor(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimary))
.setContentTitle(Html.fromHtml(remoteMessage.getData().get("title")))
.setContentText(Html.fromHtml(remoteMessage.getData().get("message")))
.setAutoCancel(true)
.setDefaults(Notification.DEFAULT_SOUND)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
createNotificationChannel();
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
notificationManager.notify(notificationId, notificationBuilder.build());
}
private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = "Exchange Customer";
String description = "Sales Buddy";
String CHANNEL_ID = "100";
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
channel.setDescription(description);
getSystemService(NotificationManager.class).createNotificationChannel(channel);
}
}
}
AndroidManifest
<service android:name=".sevices.MyFirebaseNotificationService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
Permissions in Manifest
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_PROFILE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-feature
android:name="android.hardware.camera"
android:required="true" />
On Message received I've logged notification and here is logcat
2019-05-01 15:08:54.415 29417-29501/in.example.one E/NOTIF: {extras={"customerId":"5e341186-6bd4-11e9-9069-44a8422a303b"}, type=exchange, title=Test User:1556703533, message=Test User1}
2019-05-01 15:08:58.542 29417-29501/in.example.one E/NOTIF: {extras={"customerId":"5e341186-6bd4-11e9-9069-44a8422a303b"}, type=exchange, title=Test User:1556703533, message=Test User1}
here you can see same notification log is printing twice and both notifications are displaying on device
Project Gradle File
dependencies {
classpath 'com.android.tools.build:gradle:3.4.0'
classpath 'com.google.gms:google-services:4.2.0'
classpath 'io.fabric.tools:gradle:1.26.1'
}
Module Gradle File
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:design:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation 'com.android.support:recyclerview-v7:28.0.0'
implementation 'com.android.support:cardview-v7:28.0.0'
implementation 'com.squareup.picasso:picasso:2.5.2'
implementation 'com.amitshekhar.android:android-networking:1.0.2'
implementation 'com.github.WindSekirun:SectionCalendarView:1.0.5.1'
implementation 'com.github.darsh2:MultipleImageSelect:v0.0.4'
implementation 'com.bogdwellers:pinchtozoom:0.1'
implementation 'com.google.firebase:firebase-core:16.0.8'
implementation 'com.google.firebase:firebase-messaging:17.6.0'
implementation 'com.crashlytics.sdk.android:crashlytics:2.9.9'
implementation 'com.google.firebase:firebase-database:16.1.0'
}
My Php code
$extras= json_encode(['customerId' => "5e341186-6bd4-11e9-9069-44a8422a303b"]);
$data=array(
'title'=> "Test User:".time(),
'message'=> "Test User1",
'type'=> "exchange",
'extras'=>$extras
);
$notification=array(
'title'=> "Test User:".time(),
'body'=> "body1",
);
$fields = array
(
'to'=>'/topics/test-exchange-persons-sales-buddy',
'data' => $data
);
$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;
I have the same issue since yesterday (using topics too). As a workaround, until it gets fixed I'm doing this in my FirebaseMessagingService:
private static ArrayList<Long> alreadyNotifiedTimestamps = new ArrayList<>();
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
if (!isDuplicate(remoteMessage.getSentTime())) {
// send notificaiton here
}
}
// Workaround for Firebase duplicate pushes
private boolean isDuplicate(long timestamp) {
if (alreadyNotifiedTimestamps.contains(timestamp)) {
alreadyNotifiedTimestamps.remove(timestamp);
return true;
} else {
alreadyNotifiedTimestamps.add(timestamp);
}
return false;
}
I have tha same problem but with Firebase Messaging Topics. I recive two notification beacuase "onMessageReceived" called twice like you. Maybe a problem from FCM today?
I had also faced similar issue, Because of implementation 'com.google.firebase:firebase-messaging:17.6.0', So then i just used implementation 'com.google.firebase:firebase-messaging:17.3.3' version of messaging then everything worked correctly
i am trying Edujugon Push Notification laravel; all configuration be correct.
my push notification code is
$push = new PushNotification('fcm');
$push->setMessage([
'notification' => [
'title'=>'This is the title',
'body'=>'This is the message',
'sound' => 'default'
],
'data' => [
'extraPayLoad1' => 'value1',
'extraPayLoad2' => 'value2'
]
])
->setApiKey('AAAAv7w78uY:APA91bF73GY1AcZvBh84K2matRxFwWB0VQysqlDzsLBtrmVRbRN0e6T2Lxasiv-sNfWaNQwqgltTaiaL0rZVC5TKzwfZRgrxb30B4jkl2bzJ9DViZsbGVdQMNOJ78FtOfwcUCgvUj_XC7jLdargjnfKQAD0ecbWMlA')
->setDevicesToken('fj6Sx3zYjhM:APA91bE3cas4LPX-T9jJ-7YgKrMIYOiD5Brjf9AgqvCUsSN7OygZEX3qhQ1F4RxCZfsvSCHNV9gq15NL26k62KBuWqpX4G9nrSQHT3ddabCTRwinqbmpt53gtdCgakaW5LvSxA1t1-iiZS8at8pW7W9o5Gyv2mBSEw');
$push = $push->send();
Please refer https://packagist.org/packages/edujugon/push-notification
$push->setMessage([
'notification' => [
'title'=>'This is the title',
'body'=>'This is the message',
'sound' => 'default'
],
'data' => [
'extraPayLoad1' => 'value1',
'extraPayLoad2' => 'value2'
]
])
->setApiKey('Server-API-Key')
->setDevicesToken(['deviceToken1','deviceToken2','deviceToken3'...]);
used this package LARAVEL-FCM EASY TO USED
I have also integrated push notification in laravel using below code, hope it helps you :
function sendPushNotification($fcm_token, $title, $message, $id="") {
$push_notification_key = Config::get('settings.PUSH_NOTIFICATION_KEY');
$url = "https://fcm.googleapis.com/fcm/send";
$header = array("authorization: key=" . $push_notification_key . "",
"content-type: application/json"
);
$postdata = '{
"to" : "' . $fcm_token . '",
"notification" : {
"title":"' . $title . '",
"text" : "' . $message . '"
},
"data" : {
"id" : "'.$id.'",
"title":"' . $title . '",
"description" : "' . $message . '",
"text" : "' . $message . '",
"is_read": 0
}
}';
$ch = curl_init();
$timeout = 120;
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
// Get URL content
$result = curl_exec($ch);
// close handle to release resources
curl_close($ch);
return $result;
}
I have read few threads here about this issue but doesn't seem to solve it, not sure what I am missing, here is my code that's supposed to send notifications to all devices, but it seems to miss some out, any help is appreciated:
foreach ($devices as $deviceArray) {
$regIds[] = $deviceArray['device_id'];
}
$pusher->notify($regIds, $msg);
the notify function:
public function notify($regIds, $data)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, self::GOOGLE_GCM_URL);
if (!is_null($this->proxy)) {
curl_setopt($ch, CURLOPT_PROXY, $this->proxy);
}
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $this->getHeaders());
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, $this->getPostFields($regIds, $data));
$result = curl_exec($ch);
if ($result === false) {
throw new \Exception(curl_error($ch));
}
curl_close($ch);
$this->output = $result;
}
private function getHeaders()
{
$tempArray[0] = 'Authorization: key=' . $this->apiKey;
$tempArray[1] = 'Content-Type: application/json';
return $tempArray;
}
private function getPostFields($regIds, $data)
{
$fields = array(
'registration_ids' => is_string($regIds) ? array($regIds) : $regIds,
'data' => is_string($data) ? array( 'message' => $data) : $data,
);
return json_encode($fields, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE);
}
i try to send message from my server to google cloud server, but i have problem with it...
i get server key(Key for server applications), set it to this code:
$headers = array(
'Authorization: key=' .My server 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);
after sending message i have such result:
Unauthorized
Error 401
I use such ip:78.47.150.20
but when i use test ip 0.0.0.0/0 i haven't any problems....
function sendNotification($registrationIdsArray, $messageData) {
$apiKey = "YOUR_API_KEY";
$headers = array("Content-Type:" . "application/json", "Authorization:" . "key=" . $apiKey);
$data = array(
'data' => $messageData,
'registration_ids' => $registrationIdsArray
);
$ch = curl_init();
curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers );
curl_setopt( $ch, CURLOPT_URL, "https://android.googleapis.com/gcm/send" );
curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, 0 );
curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, 0 );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch, CURLOPT_POSTFIELDS, json_encode($data) );
$response = curl_exec($ch);
curl_close($ch);
return $response;
}