It's my first time to use FCM, I created a new project in android studio, then I clicked on "tools" and I chose Firebase, I followed all the steps in this window
and I copied and pasted these blocks of code exactly in the same location as mentioned
here's my Java code
public class ZeftToken extends FirebaseInstanceIdService {
#Override
public void onTokenRefresh() {
// Get updated InstanceID token.
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Log.d("zeft", "Refreshed token: " + refreshedToken);
}
}
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
This is my Manifest file:
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
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=".ZeftToken">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
</application>
When I run the application I don't get the token in the logcat and it's completely missing. I don't know what's wrong.
Update
extend FirebaseMessagingService
use onNewToken instead of onTokenRefresh
getToken() method is now deprecated
#Override
public void onNewToken(String token) {
Log.d(TAG, "Refreshed token: " + token);
// If you want to send messages to this application instance or
// manage this apps subscriptions on the server side, send the
// Instance ID token to your app server.
sendRegistrationToServer(token);
}
if you want to retrieve token in you activity
use the below code .getInstanceId() instead of .getToken() method
FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener( MyActivity.this, new OnSuccessListener<InstanceIdResult>() {
#Override
public void onSuccess(InstanceIdResult instanceIdResult) {
String newToken = instanceIdResult.getToken();
Log.e("newToken",newToken);
}
});
I solved my solution with this function below;
public void savePushToken(){
if (!settings.hasData(Keys.pushTokenSaved) ){
FirebaseMessaging messaging = FirebaseMessaging.getInstance();
messaging.getToken().addOnSuccessListener(s -> {
Log.d("ON TOKEN",s);
pushToken = s;
JSONObject params = new JSONObject();
JSONObject info = new JSONObject();
try {
info.put("os","android");
info.put( "framework", "flutter");
info.put( "cihaz_bilgisi", new JSONObject());
params.put("token",pushToken);
params.put("device_info",info);
} catch (JSONException e) {
e.printStackTrace();
}
NetworkHelper.request(MyMethod.put, Links.savePushToken, params, false, false,
response->{
Log.d("PUSH_REQUEST",response.toString());
if (response.has("successful")||response.optString("message").contains("Integrity constraint violation: 1062 Duplicate entry")) {
settings.setBool(Keys.pushTokenSaved, true);
}
});
});
}
}
if everyting other good. (i hope you have json file provided by fcm service ? )
just move
FirebaseInstanceId.getInstance().getToken();
to for example your application or mainactivity
if u have error ( null pointer exception ) than you firebase not initialized. Check againe tutorial. And dont forget about google-json
Maybe you've already received the token in previous instance of app. The method onTokenRefresh only gets called when it is created or updated. It will not be executed in all app instances. Clear app data or uninstall app and run it again so that new token will be created and you can see it in the log.
Make sure to store the received token in shared preferences or database for future usage.
Reference Get started with Firebase
Cross check the file path of google-service.json as specified
Check the console for FCM token when you launch the app(Main Activity)
Android Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="in.sdev.android.stackoverflow">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
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=".firebase.MyFirebaseInstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
<service
android:name=".firebase.MyFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
</application>
</manifest>
Main Activity
package in.sdev.android.stackoverflow;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import com.google.firebase.iid.FirebaseInstanceId;
public class MainActivity extends AppCompatActivity {
public static String TAG = "MainActivity";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Log.d(TAG, "FCM token: " + refreshedToken);
}
}
Sample Firebase Package
MyFirebaseInstanceIDService.java
package in.sdev.android.stackoverflow.firebase;
import android.util.Log;
import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.iid.FirebaseInstanceIdService;
import static android.content.ContentValues.TAG;
public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService {
#Override
public void onTokenRefresh() {
// Get updated InstanceID token.
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Log.d(TAG, "Refreshed token: " + refreshedToken);
// If you want to send messages to this application instance or
// manage this apps subscriptions on the server side, send the
// Instance ID token to your app server.
sendRegistrationToServer(refreshedToken);
}
public void sendRegistrationToServer(String token){
Log.v("FirebaseService", "Token " + token);
}
}
MyFirebaseMessagingService.java
package in.sdev.android.stackoverflow.firebase;
import android.util.Log;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
public class MyFirebaseMessagingService extends FirebaseMessagingService {
public static String TAG = "MyFirebaseMsgService";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// ...
// TODO(developer): Handle FCM messages here.
Log.d(TAG, "From: " + remoteMessage.getFrom());
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
Log.d(TAG, "Message data payload: " + remoteMessage.getData());
}
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
}
// Also if you intend on generating your own notifications as a result of a received FCM
// message, here is where that should be initiated. See sendNotification method below.
}
}
Hope this helps
Related
I have converted a project from GCM to FCM but onTokenRefresh() function not call.
I have followed this link :
https://developers.google.com/cloud-messaging/android/android-migrate-fcm
I have completed follow step
Add Firebase project and add application with SHA1 key
Remove all code of GCM from my android project
Add FCM code
FCM Code:
In manifest.xml
<service android:name=".Commonclass.MyFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<service android:name=".Commonclass.MyFirebaseInstanceIDService" >
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
Create two java file
MyFirebaseInstanceIDService.java
public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService {
private static final String TAG = "MyFirebaseIIDService";
#Override
public void onTokenRefresh() {
Log.d(TAG, "Refreshed token start");
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Log.d(TAG, "Refreshed token: " + refreshedToken);
GlobalClass.strDeviceToken = refreshedToken;
Log.e("token",GlobalClass.strDeviceToken);
Log.d(TAG, "Refreshed token end");
storeToken(refreshedToken);
}
private void storeToken(String token) {
//saving the token on shared preferences
SharedPreferences sharedPreferences = getSharedPreferences(GlobalClass.SHARED_PREF_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(GlobalClass.prefFCMToen, token);
editor.apply();
}
}
MyFirebaseMessagingService.java
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "MyFirebaseMsgService";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
if (remoteMessage.getData().size() > 0) {
//Log.e(TAG, "Data Payload: " + remoteMessage.getData().toString());
try {
Map<String, String> params = remoteMessage.getData();
JSONObject json = new JSONObject(params);
} catch (Exception e) {
Log.e(TAG, "Exception: " + e.getMessage());
}
}
}
}
I follow this google guidelines
https://firebase.google.com/docs/reference/android/com/google/firebase/iid/FirebaseInstanceId
every time I reinstall application but not call onTokenRefresh().
The onTokenRefresh() method doesn't necessarily get called every time the app starts or if it is newly installed. It only triggers on some scenarios (see my answer here).
The implementation looks correct. In order to get the current token, you must first call getToken() somewhere similar to a MainActivity.
The getToken() method can immediately return the current token or null. If its null, it means that the FCM server is not yet finished generating or sending the token back to the client, in which case onTokenRefresh() would trigger upon completion.
I have created one new app for push notification in https://console.firebase.google.com. I have followed all steps mentioned at last it shows -unknown app- under the head Targeting user segment.
How to test push notification in firebase?
AndroidManifest.xml
`
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
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>
</application>
`
First, for using firebase push notifications add the dependencies
dependencies {
compile 'com.google.firebase:firebase-messaging:11.6.2' // this line must be included to use FCM
}
Add a service that extends FirebaseMessagingService
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "FCM Service";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// TODO: Handle FCM messages here.
// If the application is in the foreground handle both data and notification messages here.
// Also if you intend on generating your own notifications as a result of a received FCM
// message, here is where that should be initiated.
Log.d(TAG, "From: " + remoteMessage.getFrom());
Log.d(TAG, "Notification Message Body: " + remoteMessage.getNotification().getBody());
}
}
In your Manifest add this
<service android:name=".MyFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
Add a service that extends FirebaseInstanceIdService
public class FirebaseIDService extends FirebaseInstanceIdService {
private static final String TAG = "FirebaseIDService";
#Override
public void onTokenRefresh() {
// Get updated InstanceID token.
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Log.d(TAG, "Refreshed token: " + refreshedToken);
// TODO: Implement this method to send any registration to your app's servers.
sendRegistrationToServer(refreshedToken);
}
/**
* Persist token to third-party servers.
*
* Modify this method to associate the user's FCM InstanceID token with any server-side account
* maintained by your application.
*
* #param token The new token.
*/
private void sendRegistrationToServer(String token) {
// Add custom implementation, as needed.
}
}
Add it into the AndroidManifest.xml file, this makes sure that the service is loaded
<service android:name=".FirebaseIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
You are done implementing firebase push notifications !
Test and send your first push notification from firebase console !
hope it helped
For more info check this: https://firebase.google.com/docs/cloud-messaging/android/client?hl
happy coding !
I am using FCM for notification and it is working good in all scenarios in Foreground and background. My problem is when I am logout from my application and another user send me message, I am not getting any notification as I am logout which is fine, but when I again login in my application I want to receive that old unread notification so how to do this any help would be appreciated following is the code I used
public class FirebaseIDService extends FirebaseInstanceIdService {
private static final String TAG = "FirebaseIDService";
Context ctx = this;
#Override
public void onTokenRefresh() {
// Get updated InstanceID token.
try {
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Log.d(TAG, "Refreshed token: " + refreshedToken);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "FCM Service";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
FirebaseDatabase.getInstance().setPersistenceEnabled(true);
Log.e("remote", remoteMessage.getData().get("type") + "");
Log.e("remoteMessage", remoteMessage.getData() + "");
Log.e("remoteMessagebody", remoteMessage.getData().get("body") + "");
// handling other data also according to my app which i am not mentioning
}
}
I have used this code for fetching old notification but didnot worked
FirebaseDatabase.getInstance().setPersistenceEnabled(true);
and in manifest
<service
android:name=".MyFirebaseMessagingService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<service android:name=".FirebaseIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
and in gradle
compile 'com.google.firebase:firebase-messaging:9.2.1'
An FCM message has its own lifetime -- 4 weeks default, could be modified by setting time_to_live in your payload. After that time, the message would be discarded.
What you could do is implement that each notif is saved in a your Server DB, if it is not read yet and you detect that the user re-logs in, re-send them as push notifications, or simply retrieve them in your app and display them as notifications.
I'm trying to migrate Android client app from Google Cloud Messaging to Firebase Cloud Messaging. I strictly followed an official tutorial, but didn't succeed - onMessageReceived() method is not called when app in foreground.
So here are code snippets that I touched.
build.gradle (project level)
dependencies {
//other stuff
classpath 'com.google.gms:google-services:3.0.0'
}
build.gradle (app level)
apply plugin: 'com.google.gms.google-services' //this line in the bottom
and
dependencies {
//other stuff here
compile 'com.google.firebase:firebase-messaging:9.0.0'
}
AndroidManifest.xml
<service android:name=".service.FirebaseService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
and
<service
android:name=".service.MyInstanceIDListenerService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
and
<service
android:name=".service.RegistrationIntentService"
android:exported="false" />
as childs of <application> tag.
MyInstanceIDListenerService.java
public class MyInstanceIDListenerService extends FirebaseInstanceIdService {
final String TAG = "Firebase instance id";
#Override
public void onTokenRefresh() {
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Log.d(TAG, "Refreshed token: " + refreshedToken);
sendRegistrationToServer(refreshedToken);
}
private void sendRegistrationToServer(String token) {
Intent intent = new Intent(RegistrationIntentServiceEvent.TOKEN);
intent.putExtra(RegistrationIntentServiceEvent.TOKEN, token);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
}
FirebaseService.java
public class FirebaseService extends FirebaseMessagingService {
//OtherStuff
#Override
public void onMessageReceived(RemoteMessage message){
String from = message.getFrom();
Map data = message.getData();
Log.d(TAG, "Message: " + from); //Never appears in logcat
//other stuff
}
}
RegistrationIntentService
public class RegistrationIntentService extends IntentService {
private static final String TAG = "RegIntentService";
public RegistrationIntentService() {
super(TAG);
}
#Override
protected void onHandleIntent(Intent intent) {
try {
synchronized (TAG) {
String token = FirebaseInstanceId.getInstance().getToken();
Log.i(TAG, "GCM Registration Token: " + token);//This works fine
//and shows this line - 12-19 17:59:33.295 3146-5386/ru.bpc.mobilebank.bpc I/RegIntentService: GCM Registration Token: *some_token*
sendRegistrationToServer(token);
}
} catch (Exception e) {
Log.d(TAG, "Failed to complete token refresh", e);
}
}
private void sendRegistrationToServer(String token) {
Intent intent = new Intent(RegistrationIntentServiceEvent.TOKEN);
intent.putExtra(RegistrationIntentServiceEvent.TOKEN, token);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
}
Please, tell if i did something wrong and why registrations seems to be done properly, but the onMessageReceived() method is never called even if the app is in foreground. Thanks in advance.
P.S. By the way, is adding SHA-1 keys in Firebase console necessary? maybe this could cause the problem? But Firebase says this action is optional.
if you are using FCM then you should replace this
<service android:name=".service.GcmService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
to
<service android:name=".service.FirebaseService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
your service not registered properly..
I'm trying to setup a system where an Android mobile phone receives notification from a server: for this task we have chosen Firebase.
While the application is in background everything works fine: after I push a message from the firebase console a notification appears on the system tray and, after the message is clicked by the user, an Intent with extra data is sent to the Activity.
My problem is uniquely when the application is already in foreground. The firebase notification is pretty clear: if the application is in foreground, no matter which type of message is sent by the server, OnMessageReceived is never called... so why it fails with my simple app? Some notes to help you solve this issue:
we're working with Android Studio 2.1.2;
"it.bagozi.ada.tutorial.firebase" contains both classes (as you might deduce from the pacakge declaration);
Below you can find all the source code used:
Main Activity
package it.bagozi.ada.tutorial.firebase;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
private TextView notification;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.notification = (TextView) this.findViewById(R.id.notification_setter);
Intent i = this.getIntent();
Log.e(TAG, "Intent from Activity caller: " + i);
if (getIntent().getExtras() != null) {
for (String key : getIntent().getExtras().keySet()) {
String value = getIntent().getExtras().getString(key);
Log.d(TAG, "Key: " + key + " Value: " + value);
}
}
}
}
FirebaseNotificationService
package it.bagozi.ada.tutorial.firebase;
import android.util.Log;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
public class FirebaseNotificationService extends FirebaseMessagingService {
private static final String TAG = FirebaseNotificationService.class.getSimpleName();
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// TODO(developer): Handle FCM messages here.
Log.e(TAG, "From: " + remoteMessage.getFrom());
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
Log.e(TAG, "Message data payload: " + remoteMessage.getData());
}
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
Log.e(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
}
// Also if you intend on generating your own notifications as a result of a received FCM
// message, here is where that should be initiated. See sendNotification method below.
}
}
Android Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="it.bagozi.ada.tutorial.firebase">
<service android:name=".FirebaseNotificationService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<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>
</application>
</manifest>
Make the service declaration in your manifest a child of the "application" tag!