How to get Firebase Cloud Messaging token in Xamarin? - android

I have a Xamarin android application and I need to get Firebase Cloud Messaging Token.
I added a file with the following class in my Android Project :
[Service]
[IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
[IntentFilter(new[] { "com.google.firebase.INSTANCE_ID_EVENT" })]
public class MyFirebaseIIDService : FirebaseMessagingService
{
const string TAG = "MyFirebaseMsgService";
public override void OnNewToken(string token)
{
base.OnNewToken(token); // << Breakpoint here
SendRegistrationToServer(token);
}
public void SendRegistrationToServer(string token)
{
// Do something with the token
}
}
and my AndroidManifest.xml :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="13" android:versionName="13.1" package="com.MyApp.app" android:installLocation="internalOnly">
<uses-sdk android:minSdkVersion="18" android:targetSdkVersion="30" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CAMERA" />
<application android:label="MyApp" android:icon="#mipmap/launcher_foreground" android:hardwareAccelerated="true" android:debuggable="true">
<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>
</application>
</manifest>
I deploy the application to an emulated device but the breakpoint is never reached. The app is deployed though and running.
I was wondering if this code is enough or whether this class has to be referenced somewhere else.
I'm aware that this code is run only once when the application is installed. So every time I uninstall the application before testing again.
Does anyone have an idea how to solve that please ?
Thanks.
Cheers,

If you want to get the Firebase Cloud Messaging Token, you could use the code below.
var FCMtoken = FirebaseMessaging.Instance.GetToken().GetResult(Java.Lang.Class.FromType(typeof(InstallationTokenResult))).ToString();
This service MyFirebaseIIDService implements an OnTokenRefresh method that is invoked when the registration token is initially created or changed.
OnTokenRefresh is invoked infrequently: it is used to update the token under the following 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.
You could check the MS docs for more details. https://learn.microsoft.com/en-us/xamarin/android/data-cloud/google-messaging/remote-notifications-with-fcm?tabs=windows#implement-the-firebase-instance-id-service

Related

Xamarin Google Cloud Messaging Not Working

I am trying to setup a basic Xamarin app with push notifications for Android. I followed the demo here and all seemed to be going well. The application log shows the registration token received using the following code:
using System;
using Android.App;
using Android.Content;
using Android.Util;
using Android.Gms.Gcm;
using Android.Gms.Gcm.Iid;
namespace HawkProject.Droid {
[Service(Exported = false)]
class RegistrationIntentService : IntentService
{
static object locker = new object();
public RegistrationIntentService() : base("RegistrationIntentService") { }
protected override void OnHandleIntent (Intent intent)
{
try
{
Log.Info ("RegistrationIntentService", "Calling InstanceID.GetToken");
lock (locker)
{
var instanceID = InstanceID.GetInstance (this);
var token = instanceID.GetToken (
"1015213323461", GoogleCloudMessaging.InstanceIdScope, null);
Log.Info ("RegistrationIntentService", "GCM Registration Token: " + token);
//SendRegistrationToAppServer (token);
//Subscribe (token);
}
}
catch (Exception e)
{
Log.Debug("RegistrationIntentService", "Failed to get a registration token");
Log.Debug("RegistrationIntentService", e.Message);
return;
}
}
void SendRegistrationToAppServer (string token)
{
// Add custom implementation here as needed.
}
void Subscribe (string token)
{
var pubSub = GcmPubSub.GetInstance(this);
pubSub.Subscribe(token, "/topics/hawkglobal", null);
}
}
}
Application Log returns:
[RegistrationIntentService] Calling InstanceID.GetToken
[RegistrationIntentService] GCM Registration Token: dz8yxsF61tc:APA91bFpHBPsJuGUN2Yh5Hv9CyuAgyIUP4qthhNE79rJUOvLH__ildlVOaP9Q-X1lBpDk69BDRbnzDl4kdEdJBjyudwiVfRZnVR4trQwcM8JZYIEqMNFiXAy61RSjD2MWnC2kmNLj1Ev
My manifest is as follows:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="auto" package="com.gcs.hawkproject" android:versionCode="1" android:versionName="start">
<uses-sdk android:minSdkVersion="15" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="com.gcs.hawkproject.permission.C2D_MESSAGE" />
<permission android:name="com.gcs.hawkproject.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<application android:label="Hawk" android:icon="#drawable/log"></application>
<application android:label="RemoteNotifications" android:icon="#drawable/Icon">
<receiver android:name="com.google.android.gms.gcm.GcmReceiver"
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="com.gcs.hawkproject" />
</intent-filter>
</receiver>
<service
android:name="com.gcs.hawkproject.MyGcmListenerService"
android:exported="false" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
<service
android:name="com.gcs.hawkproject.MyInstanceIDListenerService"
android:exported="false">
<intent-filter>
<action android:name="com.google.android.gms.iid.InstanceID"/>
</intent-filter>
</service>
</application>
</manifest>
All seems to be going well, but when i try to send a message, I get the following results:
POST:
{
"data" : { "message" : "This is a test" },
"to" : "dz8yxsF61tc:APA91bFpHBPsJuGUN2Yh5Hv9CyuAgyIUP4qthhNE79rJUOvLH__ildlVOaP9Q-X1lBpDk69BDRbnzDl4kdEdJBjyudwiVfRZnVR4trQwcM8JZYIEqMNFiXAy61RSjD2MWnC2kmNLj1Ev"
}
RESPONSE
{
"multicast_id":5139152955408512939,
"success":0,"failure":1,"canonical_ids":0,
"results": [{"error":"NotRegistered"}]
}
Any thoughts? I am new to both Xamarin and GCM, so I am fumbling around for hours with no success.
I have other code from the demo as well that i can post if necessary.
Thanks in advance.
Change
using Android.Gms.Gcm.Iid;
to
using Android.Gms.Iid;
I would suggest try the following:
(1) Uninstall and Reinstall the application, get a new notification token from GCM, try push to the new token again.
(2) Double check the Project id "1015213323461", is it possible that the sender_id does not match with the server certificate used to send the notification?
(3) com.gcs.hawkproject is this project id matching the one you registered in Google Developer console?
There is a Xamarin Studio deployment issue that result in those NotRegistered errors, my workaround is detailed here.
Is this is a new GCM project? You should be now using FCM - Firebase Cloud Messaging.
From GCM website:
Firebase Cloud Messaging (FCM) is the new version of GCM. It inherits
the reliable and scalable GCM infrastructure, plus new features! See
the FAQ to learn more. If you are integrating messaging in a new app,
start with FCM. GCM users are strongly recommended to upgrade to FCM,
in order to benefit from new FCM features today and in the future.
I think that your GCM key might not be valid now. You should create your FCM project in here:
https://firebase.google.com/docs/cloud-messaging/

onMessageReceived() not getting called

Like some others, I too can't seem to get GCM to work. In particular, I cannot see why execution is not reaching GcmListenerService.onMessageReceived().
I have followed the official docs and have managed to (I think) do the following correctly:
get a registration token using InstanceID
send this token back to my local Rails server for storage
subsequently, use this same token to send a message (no notification) using GCM.
The relevant bits of code are as follows. Please let me know if something is amiss.
AndroidManifest.xml
<!-- GCM specific -->
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission android:name="com.gradians.prepwell.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.gradians.prepwell.permission.C2D_MESSAGE"/>
<receiver android:name="com.google.android.gms.gcm.GcmReceiver" 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="com.gradians.prepwell" />
</intent-filter>
</receiver>
<service android:name=".services.MyGcmListenerService" android:exported="false">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
<service android:name=".services.MyInstanceIDListenerService"
android:exported="false">
<intent-filter>
<action android:name="com.google.android.gms.iid.InstanceID" />
</intent-filter>
</service>
<service android:name=".services.RegisterService"
android:exported="false" />
MyGcmListenerService.java (not getting called)
public class MyGcmListenerService extends GcmListenerService {
#Override
public void onMessageReceived(String from, Bundle data) {
Log.i("debug", "onMessageReceived") ;
}
}
Rails Code
def post_potd
api_key = "AIz......-_Y"
gcm = GCM.new(api_key)
reg_ids = Device.all.map(&:gcm_token)
payload = {
data: { message: "Hello Dude!" }
}
response = gcm.send reg_ids, payload
render json: response, status: :ok
end
The JSON Response to above Rails code seems to be ok (status_code = 200, response='success' etc.). So, I am guessing GCM has no issues with the request that was posted.
But are there any other common pitfalls in GCM integration that one must watch for? And how can one check for them?
I thought I had done everything right. But I have obviously have missed something. Hence, any insights / tips / advice would be most helpful.
Thanks
Abhinav.

Can't send push from Parse.com

I had a project with Parse in my app, but I've changed the project (and so the keys) and my pushes (test or normal) doesn't get sent from Parse.
When I try to send them I'm notified that it's going to be received by 2 recipients:
My Client push is ENABLED:
Although I think it's not needed, I've got my GCM credentials:
I've tried with a custom ParsePushBroadcastReceiver extended on Android and logging onReceive
I've tried to sign as release and debug.
I've tried with Wi-Fi, 3G and 4G.
I've tried to clear data, uninstall the app, rebooting.
My permissions on AndroidManifest.xml are:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission android:protectionLevel="signature"
android:name="taggie.me.permission.C2D_MESSAGE" />
<uses-permission android:name="taggie.me.permission.C2D_MESSAGE" />
My application is:
<application
android:name=".MainApplication"
android:allowBackup="true"
android:icon="#drawable/logo_help"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
which code is:
public class MainApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
Parse.initialize(this, "YBi4ki505TcwKSNEIW7gkFCdWvjHC9yNJmrZHBGR", "APwUw3laazYRhvkSRwZZqpxsROUjH5jWP6QzeHiq");
ParseInstallation.getCurrentInstallation().saveInBackground();
}
}
and the rest of my AndroidManifest.xml is:
<service android:name="com.parse.PushService" />
<receiver android:name="com.parse.ParseBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.USER_PRESENT" />
</intent-filter>
</receiver>
<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" />
<category android:name="taggie.me" />
</intent-filter>
</receiver>
<receiver android:name="com.parse.ParsePushBroadcastReceiver" android:exported="false">
<intent-filter>
<action android:name="com.parse.push.intent.RECEIVE" />
<action android:name="com.parse.push.intent.DELETE" />
<action android:name="com.parse.push.intent.OPEN" />
</intent-filter>
</receiver>
<meta-data android:name="com.parse.push.gcm_sender_id"
android:value="id:10321_and_the_rest_of_my_number" />;
but THE PROBLEM IS HERE
I don't get notifications, and when I send them I can see this:
Does anyone has a clue before shooting myself? Thank you :)
This is incredible, I've tried to send the apk to one friend of mine... and he gets the push notifications but I don't! why could it be possible?
I've just opened the port 8253 as I've seen some posts reporting this, but it's still not working. :'(
I had a similar issue that was resolved in a strange way, but still - might help:
if you re-install (actually re-deploy, sometimes uninstalling sometimes just running over an existing apk) your application on a device, it might create several entries for device tokens that point to the same actual device (inside the Parse dashboard, go to Core, you can see the full table there), in which case - the system doesn't always know which is the correct physical device.
this might explain:
a. the dashboard telling you it will send more than 1 message (assuming only 1 was supposed to be sent).
b. your friend getting the push (he has only 1 valid device token)
Anyway - the refresh button on the Core page didn't help, but - manualy sending a push from the dashboard would result in the device receiving multiple pushes (for the number of duplicates it had in the table), and then, re-entering the Core table page would automatically clear the duplicates.
from there on - Pushes got back to normal.
you might need another clean, complete removal and re-installation on the device.
Hope this Helps!
Note: GCM Credentials were'nt needed in my case.
The main problem is I was working with Genymotion.
Being a simulator, push notifications should ARRIVE or NOT ARRIVE at all, but they were arriving sometimes. I can't explain why.
In your parseApplication class declare the channel. If you are sending notifications you have to set the channel. See this ParsePush.subscribeInBackground . It is describing the channel .
public class ParseApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
System.out.println("Application");
Parse.initialize(this, "86q5mwgypd1Q2URFV6kJh5MBPmUpuPvoN3lTdeWx", "OhrkrJTuTwtbMprYtiywnQ3f4wnQdr5pitmI7tNt");
ParsePush.subscribeInBackground("temboo", new SaveCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
Log.d("com.parse.push", "successfully subscribed to the broadcast channel.");
} else {
Log.e("com.parse.push", "failed to subscribe for push", e);
Toast.makeText(ParseApplication.this, "Failed to subscribe for push.", Toast.LENGTH_SHORT).show();
}
}
});
This works for me.
Parse.enableLocalDatastore(this);
// Add your initialization code here
Parse.initialize(this, APP_ID, CL_ID);
ParseInstallation.getCurrentInstallation().saveInBackground();
ParseUser.enableAutomaticUser();
ParseACL defaultACL = new ParseACL();
// Optionally enable public read access.
// defaultACL.setPublicReadAccess(true);
ParseACL.setDefaultACL(defaultACL, true);
// IF NEEADED
String topic ="YOUR_TOPIC";
System.out.println(topic);
ParsePush.subscribeInBackground(topic, new SaveCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
Log.d("com.parse.push",
"successfully subscribed ");
} else {
Log.e("com.parse.push", "failed ", e);
}
}
});

PARSE: Push Notifications "deviceToken" undefined

This is the situation in my Installation page on Parse Console:
As you see some devices have the "deviceToken" and some do not have the "deviceToken". This is not good because every device should have the deviceToken in order to work.
How is this possible? This is a serious problem because the ones that do not have the deviceToken do not receive push notifications!
I've followed all the instructions on Parse.com and implemented everything as they said, even with the help of their blank project and with the help of various questions on the web. But nothing fixed my problem and now I can't do anything.
The only thing I can think about is that before my application (it is already on the Store) used to use Google Cloud Messaging and then with this new update I've decided to change the system and use Parse removing completely GCM system. Is there maybe a conflict between the two systems?
I need to fix this as you can imagine this is a serious bug and now 3/4 of my users do not receive push notifications.
If you download the app and install it: everything is good, the deviceToken is ok. If you update the app because there already was a version with GCM on the device:
some devices register in Parse good, without any problem
some devices register in Parse but without the deviceToken
For the devices that do not have the deviceToken I've tried a lot of things: inserting a deviceToken manually, uninstall and reinstall the application, delete the specific row on Parse, etc. But nothing good... Still facing this problem.
MY CODE
Application.java
public class Application extends android.app.Application {
public Application() {
}
#Override
public void onCreate() {
super.onCreate();
// Initialize the Parse SDK.
Parse.initialize(this, "x", "x");
// Specify an Activity to handle all pushes by default.
PushService.setDefaultPushCallback(this, MainActivity.class);
}
}
MainActivity.java
In my mainActivity I just concatenate the deviceToken (in my case it is the installationId) into my userAgent: and this work fine: I always have the installationId without any problem! And this is the only thing I am doing in my MainActivity (do I need to do anything else? saveInBackground, callback, etc..?)
deviceToken = ParseInstallation.getCurrentInstallation().getInstallationId();
webSettings.setUserAgentString(userAgent + " ||" + deviceToken);
AndroidManifest.xml
<!-- Gestione del guasto-->
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- Utilizzo di internet -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- Permesso di vibrare per le push notifications -->
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<!-- Mantiene attivo il processore così da poter ricevere in qualsiasi momento le notifiche -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!-- Consente di impostare l'allarme per l'aggiornamento automatico -->
<uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>
<permission android:name="com.hoxell.hoxellbrowser.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.hoxell.hoxellbrowser.permission.C2D_MESSAGE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<application
android:name="com.hoxell.hoxellbrowser.Application"
android:allowBackup="true"
android:icon="#drawable/ic_launcher_hoxell"
android:label="#string/app_name"
android:theme="#style/AppTheme"
>
<!-- Richiesto per le applicazioni che usano Google Play Services -->
<meta-data android:name="com.google.android.gms.version" android:value="#integer/google_play_services_version" />
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:configChanges="keyboardHidden|orientation|screenSize"
android:windowSoftInputMode="adjustResize"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".SettingsActivity"></activity>
<receiver android:name=".AlarmReceiver"/>
<service android:name="com.parse.PushService" />
<receiver android:name="com.parse.ParseBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.USER_PRESENT" />
</intent-filter>
</receiver>
<receiver android:name="com.hoxell.hoxellbrowser.Receiver"
android:exported="false">
<intent-filter>
<action android:name="com.parse.push.intent.RECEIVE" />
<action android:name="com.parse.push.intent.DELETE" />
<action android:name="com.parse.push.intent.OPEN" />
</intent-filter>
</receiver>
<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" />
<category android:name="com.hoxell.hoxellbrowser" />
</intent-filter>
</receiver>
</application>
Build.gradle
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
// You must install or update the Support Repository through the SDK manager to use this dependency.
compile 'com.android.support:support-v4:20.+' //support
compile "com.google.android.gms:play-services:5.0.+" //play services
compile 'com.parse.bolts:bolts-android:1.+'
compile fileTree(dir: 'libs', include: 'Parse-*.jar')
}
I don't really know what else to do, that's why I hope that somebody can help me with this.
Thank you.
Are you using 2 user profiles at the same time on the tablet? Because I've had exactly the same problem and from my experience there is a conflict between the profiles. Infact, in my situation one device was registering 2 rows into the Parse database. One with the deviceToken and one with "undefined" deviceToken.
Unfortunately I've never solved this problem, I guess this is a bug from Parse.
It could be useful to set parse logging to verbose to help debug further:
Parse.setLogLevel(Parse.LOG_LEVEL_VERBOSE);
With that I noticed that I was using the wrong "sender_id" in my manifest:
<meta-data android:name="com.parse.push.gcm_sender_id"
android:value="id:123456789"/>
That might not be the exact solution, but LOG_LEVEL_VERBOSE might help debug this.
Some installations do have a GCM Registration Id set up in their deviceToken column, which is a good indication that your setup is correct. Is it definitely possible for an installation to lack a GCM Registration Id:
The device may not have access to Google Services Framework (e.g. Amazon Kindle Fire). If you have set up the non-GCM ParsePush receiver, pushes to these devices should still get delivered.
The app has been deleted from the device, and thus it has been unregistered from GCM. We do not automatically delete installations in this case as that could potentially lead to unintended data loss, given that you're allowed to store arbitrary data in your installation class.
Google Services Framework may have been unavailable when the device attempted to register itself.
In the first two scenarios, this is working as expected and it's not something to generally worry about.
Are those simulator users? From my experience if you are running an installation on your simulator it does not auto setup the device token.
I had been struggling with this problem for a long time until I recently realized what has been going on. Not only does the package name need to match, but you also need to include the build flavor in your declaration.
If you followed the parse tutorial and replace com.parse.starter with your package name, you are done if you have no build flavor, but if you do you need to make sure to include that as such:
com.packagename.build_flavor{debug, release, etc.}
You may create a class and extends Application to initialize your app. Such that initialize ParsePush and updateParseInstallation.
Sample code:
public class YourappApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
Parse.initialize(this,YOU_PARSE_applicationId, YOU_PARSE_clientKey);
ParseInstallation.getCurrentInstallation().saveInBackground();
ParsePush.subscribeInBackground("", new SaveCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
Log.d("com.parse.push", "successfully subscribed to the broadcast channel.");
} else {
Log.e("com.parse.push", "failed to subscribe for push", e);
}
}
});
}
public static void updateParseInstallation(ParseUser user) {
ParseInstallation installation = ParseInstallation.getCurrentInstallation();
installation.put("userId", user.getObjectId());
installation.saveInBackground();
}
}
And then in your LoginActivity: updateParseInstallation
ParseUser.logInInBackground(username, password, new LogInCallback() {
#Override
public void done(ParseUser parseUser, ParseException e) {
setProgressBarIndeterminateVisibility(false);
if(e == null){
YourappApplication.updateParseInstallation(parseUser);
Intent intent = new Intent(LoginActivity.this,
MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
}
}
});
I had similar issue after renaming module.
Try 'Clean Project' followed by 'Rebuild Project'
I had this problem but in a cordova app using the phonegap-parse-plugin. I had to edit the android java code in the plugin to fix, so effectively the same.
Try adding this save BETWEEN the Initialize and the setDefaultPushCallback:
ParseInstallation.getCurrentInstallation().save();
It has to be between them to work.
My problem was that I was missing this permission in the manifest:
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
Also I had to add meta-data just before
<service android:name="com.parse.PushService" />:
<meta-data
android:name="com.parse.APPLICATION_ID"
android:value="YourParseApplicationID" />
<meta-data
android:name="com.parse.CLIENT_KEY"
android:value="YourParseClientKey" />
Now check if you can get the deviceToken. Also check your app dashboard in Parse if everything is ok.
I dont know if tghis helps anyone but I was able to get the device token and notification correctly after removing this line from my Application Class containing parse intalation. here is the code. the commented line (removed line) made everything work properly. Can anyone explain why this works?
package com.test.android.push;
import android.app.Application;
import com.parse.Parse;
import com.parse.ParseInstallation;
import com.parse.ParsePush;
public class FarrApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
Parse.initialize(this, "xxxx", "xxxx");
ParseInstallation.getCurrentInstallation().saveInBackground();
ParsePush.subscribeInBackground("---"); // REMOVED AND WORKS

GCM not registering when changing package name with Gradle

In my regular build gcm works fine, but when I use flavors to change the com name things stop working. My IntentService is never being initialized. How should I set up my manifest files so that this happens?
I have added them to the developer console.
I am using gradle com.android.tools.build:gradle:0.11.+'
I get the logs
V/GCMBroadcastReceiver﹕ onReceive: com.google.android.c2dm.intent.REGISTRATION
V/GCMBroadcastReceiver﹕ GCM IntentService class: com.sample.app.dev.GCMIntentService
V/GCMBaseIntentService﹕ Acquiring wakelock
and then nothing. My custom IntentService class never gets initialized and my registrationId stays empty. My current implementation is similar to the one here: https://stackoverflow.com/a/20334397/198034
How should I set up my manifest to get gradle 0.11.+ flavors to work with gcm?
Below is a manifest in one of my flavors, I have more code in the main manifest (all needed permissions, etc), but nothing else dealing with gcm.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.sample.app"
android:versionCode="45"
android:versionName="0.6.5" >
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission android:name="com.sample.app.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.sample.app.permission.C2D_MESSAGE" />
<application
android:allowBackup="true"
android:icon="#drawable/app_icon"
android:label="#string/app_name" >
<service android:name=".GCMIntentService" />
<receiver
android:name="com.google.android.gcm.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" />
<category android:name="${packageName}" />
</intent-filter>
</receiver>
</application>
</manifest>
This was my solution:
<permission android:name="com.sample.app.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.sample.app.permission.C2D_MESSAGE" />
...
<service android:name=".GCMIntentService" />
<receiver
android:name=".MyBroadcastReceiver"
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="com.sample.app" />
</intent-filter>
</receiver>
in my manifest and mybroadcastReceiver
...
public class MyBroadcastReceiver extends GCMBroadcastReceiver
{
#Override
protected String getGCMIntentServiceClassName(Context context)
{
return GCMIntentService.class.getName();
}
}
From your manifest it looks like your app's package name is com.sample.app, which is consistent with your permission.C2D_MESSAGE definition. Your receiver's intent filter's category says ${packageName}. Hopefully that gets translated to com.sample.app too, as it should.
Other than that, your log posted above shows that your intent service is expected to be at com.sample.app.dev.GCMIntentService. That's a different package.
You seem to be using the old deprecated GCM client library, in which com.google.android.gcm.GCMBroadcastReceiver expects the intent service to be called GCMIntentService and be located in the main package of the app :
/**
* Gets the default class name of the intent service that will handle GCM
* messages.
*/
static final String getDefaultIntentServiceClassName(Context context) {
String className = context.getPackageName() +
DEFAULT_INTENT_SERVICE_CLASS_NAME;
return className;
}
Your manifest declares the intent service class to be in the main package of your app :
<service android:name=".GCMIntentService" />
All these things don't add up. Either your app's package name is com.sample.app.dev or com.sample.app. If it's the former, the manifest you posted is incorrect. If it's the latter, there is no reason for the broadcast receiver to expect the intent service class to be com.sample.app.dev.GCMIntentService.

Categories

Resources