Ackman Ackman - 1 month ago 13
Android Question

Push notifications/GCM Not working What can be the issue?

My GCM Service is not working. I have declared a few things in my manifest file which looks something like:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>

<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="com.google.android.c2dm.permission.SEND"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS" />

<permission android:name="com.xxxx.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="com.xxxx.xxxxxx.permission.C2D_MESSAGE" />

<receiver android:name=".core.push.receiver.GCMBroadcastReceiver" 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.SEND" />
<category android:name="com.xxxx.xxxxxx" />
</intent-filter>
</receiver>
<service android:name=".core.push.service.GCMIntentService" />


My Broadcast receiver code looks like:

public class GCMBroadcastReceiver extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent)
{
ComponentName messageProcessingService = new ComponentName(context.getPackageName(), GCMIntentService.class.getName());
context.startService(intent.setComponent(messageProcessingService));
setResultCode(Activity.RESULT_OK);
}
}


My Intent Service:

public class GCMIntentService extends IntentService
{
private static final int NOTIFICATION_NEW_MESSAGE = 0;

public GCMIntentService()
{
super(GCMIntentService.class.getSimpleName());
}

@Override
protected void onHandleIntent(Intent intent)
{
Bundle extras = intent.getExtras();
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);

String messageType = gcm.getMessageType(intent);

if (!extras.isEmpty())
{
if (!GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType))
{
return;
}

// TODO Make more efficient. Load message stream here, not in two places later!
int newUnreadCount = MessagingController.getInstance().getUnreadCount() + 1;
MessagingController.getInstance().prepareStream();
MessagingController.getInstance().setUnreadCount(newUnreadCount);

final boolean isUserAuthenticated = !TextUtils.isEmpty(AuthenticationController.getInstance().getAuthToken());

if (isUserAuthenticated)
{
new Handler(Looper.getMainLooper()).post(new Runnable()
{
@Override
public void run()
{
App.from(GCMIntentService.this).fire(MessagingEvent.NEW_MESSAGE);
}
});
}
else
{
displayNotification(newUnreadCount + " New Message" + (newUnreadCount > 1 ? "s" : ""), newUnreadCount);
}
}
}

private void displayNotification(CharSequence message, int eventCount)
{
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
boolean shouldDisplayMessages = preferences.getBoolean("notifications_new_message", true);

if (!shouldDisplayMessages)
{
return;
}

NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

Intent openMessagingScreen = new Intent(this, LandingActivity.class);
openMessagingScreen.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
openMessagingScreen.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

preferences.edit().putBoolean(MessagingFragment.PREF_MESSAGE_WAITING, true).apply();

PendingIntent notificationAction = PendingIntent.getActivity(this, 0, openMessagingScreen, PendingIntent.FLAG_CANCEL_CURRENT);

NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_notification)
.setContentTitle(getString(R.string.app_name))
.setStyle(new NotificationCompat.BigTextStyle().bigText(message))
.setContentText(message)
.setAutoCancel(true)
.setContentIntent(notificationAction)
.setNumber(eventCount);

Notification notification = notificationBuilder.build();
notification.defaults |= Notification.DEFAULT_ALL;

try
{
notificationManager.notify(NOTIFICATION_NEW_MESSAGE, notification);
}
catch (SecurityException ex)
{
// This is required due to a bug in android
// http://stackoverflow.com/questions/13602190/java-lang-securityexception-requires-vibrate-permission-on-jelly-bean-4-2
Log.e("PPDirect", ex.getLocalizedMessage());
}
}
}


I had several questions regarding push notifications:


  1. which call back function actually checks for arrived message and is called once push notification arrives?

  2. Is it possible that since google have updated GCM to FCM I need to make updates to the key or migrate GCM to FCM?

  3. Can there be some other reason?



Any help in the matter would be much appreciated.

AL. AL.
Answer

1. which call back function actually checks for arrived message and is called once push notification arrives?

For Android, it's commonly received in onMessageReceived in the GcmListenerService. However, it may also depend whether or not the app is in background or foreground.

2. Is it possible that since google have updated GCM to FCM I need to make updates to the key or migrate GCM to FCM?

As per the note here:

Starting from Sept. 2016 new server key can only be created in the Firebase Console using the Cloud Messaging tab of the Settings panel. Existing projects that need to create a new server key can be imported in the Firebase console without affecting their existing configuration.

New users of GCM is in need of creating a Firebase projext, regardless if you are going to use FCM or not, in order to have a Server Key. For the migration steps, you can see my answer here.

3. Can there be some other reason?

This is too broad to answer. Maybe it's because of your payload structure or the implementation of tour onMessageReceived(), etc.

Comments