OnTokenRefresh never called in Xamarin Android - android

I'm trying to implement remote notifications in my Xamarin Android project. I followed step-by-step directions found in various guides but the OnTokenRefresh method is never called, even the first time, so it looks like my app does not receive any kind of token or even does not make any type of firebase registration.
I have added Firebase to my Android app and downloaded google-services.json
I included google-services.json in my Xamarin Android Project and set the Build Action to GoogleServicesJson
I inserted this code in AndroidManifest.xml
<receiver
android:name="com.google.firebase.iid.FirebaseInstanceIdInternalReceiver"
android:exported="false" />
<receiver
android:name="com.google.firebase.iid.FirebaseInstanceIdReceiver"
android:exported="true"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="${applicationId}" />
</intent-filter>
</receiver>
I created a class that extends FirebaseInstanceIdService
[Service]
[IntentFilter(new[] { "com.google.firebase.INSTANCE_ID_EVENT" })]
class FirebaseRegistrationService : FirebaseInstanceIdService
{
const string TAG = "FirebaseRegistrationService";
public override void OnTokenRefresh()
{
var refreshedToken = FirebaseInstanceId.Instance.Token;
System.Diagnostics.Debug.WriteLine(TAG, "Refreshed token: " + refreshedToken);
MainActivity.CurrentActivity.RunOnUiThread(() => RegisterDeviceOnServer(refreshedToken));
}
public void RegisterDeviceOnServer(string refreshedToken)
{
// Custom implementation
}
}
As I have already said OnTokenRefresh is never called.
What I can not understand is: who does the Firebase registration to receive a valid token?
Is there a missing directive?
Is there a missing method that makes this registration?
Why OnTokenRefresh is never called?

You should start the service in your Activity like this :
var intent = new Intent(this, typeof(FirebaseRegistrationService));
StartService(intent);
Also clean the solution once and run the app again. There is a bug in firebase for xamarin.

According to this document, (see section titled: Implement the Firebase Instance ID Service) OnTokenRefresh is only called under a few circumstances:
When the app is installed or uninstalled.
When the user deletes app data.
When the app erases the Instance ID.
When the security of the token has been compromised.
In order to trigger OnTokenRefresh, you should first uninstall the app from the device. Then when you reinstall the app and open it for the first time, OnTokenRefresh will be called.

You can avoid cleaning the solution every time by disabling
Preserve application data cache on device between deploys
under
Tools -> Options -> Xamarin -> Android Settings in VS2017 Enterprise.
This made OnTokenRefresh to be called after every redeploy.

if you are using emulator make sure you install google apps as it depends on google play services package exist in your device
if you are using Genymotion you can press install Gapps

Related

Receiving the FCM notifications multiple times on Nougat

I am using Firebase push notifications in my app. But when I am sending a notification for some event, I am getting notification's multiple times after 2-3 minutes on Nougat devices only. I am getting only a single notification on the devices which are having lower version than Nougat.
I have checked that server is sending only a single notification at a time.
I am having below dependency in my app gradle.
compile `com.google.firebase:firebase-messaging:11.8.0`
And here is the code for FCM Listener:
public class MyFcmListenerService extends FirebaseMessagingService {
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
}
}
In manifest file:
<service android:name="com.myApp.test.fcm.MyFcmListenerService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
This started happening to me when I tried to migrate from old GCM to new FCM.
You need to make sure you remove all GCM related code, including gradle (remove com.google.android.gms:play-services-gcm ) and Manifest
(remove:
<uses-permission android:name="mypackage.permission.C2D_MESSAGE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission
android:name="mypackage.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
)
Also make sure you CLEAN your project and REBUILD it, to remove any cached reference to GCM classes. The last part took me like 2 hours to figure out.
A nice trick can be to find-all (⇧⌘F) "GCM" and see if you get hits from the generated files.
Same thing was happening on me , I tried everything only in vain
Then i realised we were storing all fcm tokens of the android device from start till finish without validating or deleting them
I deleted all fcm tokens and re-logged in my app which inserted a fresh singular token in FCM tokens list in my server's db
It worked fine, I think FCM should invalidate earlier tokens before issuing new ones even across installs , multiple apks, and multiple apk debug sessions
Try to send to only 1 token , also clean build and reinstall your app

Send notification to specific user android

How can I send a notification from one user to another using Android (I'm using firebase database).
I have a student user when he clicks on a button it will send a notification to his Academic advisor.
I've watched a lot of tutorials but all of them are using notificationCompat and noificationManager and I can't specify to which user this notification will be send
Thanks
You can send notification using token..You can get token..
Create android project in android studio
Open the project & Go to >Tools>Firebase>cloud messaging>set up firebase cloud messaging>
connection to your apps firebase>Connect to firebase>Create a new project using email
Add FCM to your app
Note: You need to a gmail address for adding above 3 & 4 . These will automatically configure your gadle don't do anything...
Create a class named FirebaseIDService & paste bellow code ..
public class FirebaseIDService extends FirebaseInstanceIdService {
#Override
public void onTokenRefresh() {
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Log.e("***refreshedToken",refreshedToken);
}
}
In Manifest file you add
<service android:name=".FirebaseIDService" android:exported="true">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
You will get a toke like bellow error log
***refreshedToken: eroNxVsruNk:APA91bF5gSK4Hlt-x-Pc2ecw0D8vMHoXwdZ-JY9SSl4KNLV_wUjA76T0Icv6Cxgf8pX9eDPMT3i3UhdxY27CxcvvKX5p6wHEBaX36wvE3kGapTI3uytUCQuBfh56Ss0y419kmBklew-7
Now you will send message using this token.. to the specific device because this token generated for installing apps that means if you install this app yow will get a unique token & if your friend install same app your friend will get the toke. so you will get another unique token and preserved it .. & though these tokens you can send the message...i think will work..

Firebase Cloud Messaging not calling FirebaseInstanceId

I just updated GCM to FCM according to this guide here. The site says my service which extends FirebaseInstanceIdService will be called as soon as the token is generated. For some reason, my service is never called and onTokenRefresh is never executed.
My services are registered like this, according to the guide:
<service android:name=".fcm.FcmService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
<service android:name=".fcm.InstanceIdService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCEID_EVENT"/>
</intent-filter>
</service>
My service:
public class InstanceIdService extends FirebaseInstanceIdService {
private static final String TAG = "InstanceIdService";
#Override
public void onTokenRefresh() {
String token = FirebaseInstanceId.getInstance().getToken();
Log.e(TAG, "Got token: " + token);
}
}
The LogCat doesn't say anything about missing configuration files or else, and I can see logs about FirebaseApp and a Log entry mentioning the token, but still my service is never called.
Do I need to start this service somewhere in my activity?
Am I doing something wrong? Can someone guide me in the correct direction?
EDIT: using Log.e("TOKEN", "Token: " + FirebaseInstanceId.getInstance().getToken()); correctly prints my token, so that means it was generated successfully. The service still doesn't get called...
EDIT 2: Changing INSTANCEID_EVENT to INSTANCE_ID_EVENT fixed the issue, although I had to reinstall the app. As I already released a beta version containing the new FCM, my beta testers won't be able to subscribe to the topics to reveice incoming messages. So how should I solve that?
Thanks Endanke for figuring this out with me. It seems that the Firebase documentation is inconsistent. One page says your intent filter in your manifest file should be INSTANCE_ID_EVENT, and another says INSTANCEID_EVENT.
You should use INSTANCE_ID_EVENT, and once you make the change, you'll need to completely uninstall and reinstall your app for the changes to kick in.
FCM should be used as a replacement to GCM. In your case it looks like you have services for both FCM and GCM in your manifest. Try remove the gcm.GcmService, and only use the one that extends FirebaseInstanceId.
Make Sure that your Firebase "MyFirebaseInstanceIDService.java" file is directly under the package name tree "com.company"
Don't put them in the separate subpackage like "com.company.services". This is because your google-services.json will look for the files directly under "com.company" directory.
Add the following in your manifest application tag below meta tag (if any)
<service
android:name=".MyFirebaseInstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
You will get your TOKEN on the public void onTokenRefresh() method
PS: Download and replace the latest google-services.json from your project console.
After a ton of trial and error my issue was having tools:node="replace" in my application tag...removing it solved the issue for me
I had the same problem and by uninstalling and reinstalling the app on the device onTokenRefresh() got called once. So I guess it changed from GCM where it got called often to just getting called once when there actually is no token.
I've different build variants in my project and I've the following problem:
From: https://firebase.google.com/docs/android/setup#prerequisites
Note: If you have multiple build variants with different package names defined, each app must be added to your project in Firebase console.
Also, check the date of your phone! I once had a difference of 5-7 days! Fixing the day and reinstalling the app fixed this!
What 'Firebase Cloud Messaging' wants is:
Implement a derived class (MyFirebaseInstanceIdService) from
FirebaseInstanceIdService.
Implement the override onTokenRefresh to handle an update on the
token for the device.
In the AndroidManifest.xml reference the 'derived' class prefixed
with a ".".
MyFirebaseInstanceIdService is a 'suggested' name. I personally prefer to prefix such derived classes with an acronym or name that I use throughout the App.
onTokenRefresh() will call only one time.when your app is install first time, if you want to access token from other activity you have to call this method:
FirebaseInstanceId.getInstanceId().getToken();
just change the INSTANCE_ID_EVENT to INSTANCEID_EVENT .it worked for me

Android Push notifications not recieving

This is driving me really crazy. I am new to Android development but experienced in iOS development. I wanted to implement Parse Push notifications to an Android app and all is going fine:
The devices are registered at Parse
While sending a test Push message the Parse system tells me that the message is received
BUT: I don't receive anything on my Android test devices.
I have already created new Parse Apps and Android Studio projects but without any luck. Any help on debugging this or is this a Android studio related issue?
EDIT: I just followed the Push service quick guide so I added some lines to the Manifest and added this to my code
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_inlog);
Parse.initialize(this, "xxx", "xxx");
ParseFacebookUtils.initialize("1515015192073818");
ParseInstallation.getCurrentInstallation().saveInBackground();
Manifest:
<receiver android:name="com.parse.GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<!--
IMPORTANT: Change "com.parse.starter" to match your app's package name.
-->
<category android:name="com.pootentieel.andrew.sbpootentieel" />
</intent-filter>
</receiver>
Did you changed com.parse.starter to match your package name and have you registered push callback receiver activity?
EDIT:
goto this link github.com/ParsePlatform/PushTutorial and import the android project and change the keys. Then run the android project and send a push to see if it works. If it works check both the projects side by side to see what is causing the problem. Please mark this answer as correct if it helped thanks :)

How to receive messages using the new Google Cloud Messaging Api for Android?

I have found tons of tutorials explaining Google Cloud Messaging but all seem deprecated with the new Google Cloud Messaging Api
In fact I cannot get a valid registration id using the deprecated GcmRegistrar class!
While using the new api I can get a valid registration id and use that to perform successful requests from my server to google.
I am lost as to how will I implement a Receiver in the Android App that will enable me to actually use the received messages.
I guess GCMBaseIntentService and all relevant code is now deprecated and implemented in another way
The google docs are referring to this:
<receiver android:name=".MyReceiver" android:exported="true"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="YOUR_PACKAGE_NAME" />
</intent-filter>
</receiver>
So how could I implement this MyReceiver?
The answer was much simpler than I thought.
You no longer need gcm.jar nor gcm-server.jar.
No need for a special service like GCMIntentService
No need for the receiver to handle this action: com.google.android.c2dm.intent.REGISTRATION
Actually a developer now needs to implement his own BroadcastReceiver which is as simple as that:
in Scala
class MyReceiver extends BroadcastReceiver {
def onReceive(context: Context, intent: Intent) {
log log "we have received something!";
val extraString = Option(intent.getStringExtra("json label here"));
log log "the value of this json label is: " + extraString;
}
}

Categories

Resources