parse-community / Parse-SDK-Android

The Android SDK for Parse Platform
https://parseplatform.org/
Other
1.88k stars 739 forks source link

Push notification is not working after Upgrade 1.13.0 #525

Closed taileshrbamankar closed 7 years ago

taileshrbamankar commented 7 years ago

I upgrade my application to 1.13.0. then it subscribe on installation table but push notification is not receiving

parse-github-bot commented 7 years ago

Thank you for your feedback. We prioritize issues that have clear and concise repro steps. Please see our Bug Reporting Guidelines about what information should be added to this issue.

Please try the latest SDK. Our release notes have details about what issues were fixed in each release.

In addition, you might find the following resources helpful:

taileshrbamankar commented 7 years ago

Upgrade parse android sdk 1.8.0 to 1.13.0 last week. Previously push notification is working fine but after upgrade 1.13.0. Not getting any notification through Parse UI Dashboard and Application.

For Ionic application using parse android PSDK

Don't see any notification on device when sending notifications through parse web app or from the tutorial test button.

In Webapp, I can see notifications with Pushes Sent as 0 and In delivery report it shows 1 for PPNS - outdated device

kristokiis commented 7 years ago

do you have deviceToken or GCMSenderId field filled in installation table ?

kiis commented 7 years ago

For me the issue was that GCM is now deprecated and Google only gives FCM serverId and senderId. These are not valid in GCM server and gives me: java.lang.Exception: GCM registration error: INVALID_SENDER . So maybe adding FCM support to SDK helps in future.

parse-github-bot commented 7 years ago

This issue has not been updated for 7 days. If you have additional information to help pinpoint this issue as an SDK bug, please comment on this issue. We will close this issue in 7 days if no additional information is provided. Thank you for your feedback.

JProgrammerJules commented 7 years ago

I also don't have a GCM key, only a FCM key. Please add FCM support, I need a fix ASAP.

JProgrammerJules commented 7 years ago

Did someone fix this problem?

parse-github-bot commented 7 years ago

This issue has not been updated for 7 days. If you have additional information to help pinpoint this issue as an SDK bug, please comment on this issue. We will close this issue in 7 days if no additional information is provided. Thank you for your feedback.

summers314 commented 7 years ago

Same. Up until around Sept 20th, the Installations have "gcm" written in the pushType column and have a deviceToken. However, sometime around Oct 5th, pushType & deviceToken is 'undefined'.

Also, GCMsenderId is undefined since July 22nd (in my Installation table). Is there some server side migration that is causing this?

Edit: Parse SDK 1.13.0 Android

In my case no upgradation of library has been done. I have been using 1.13.0 since the beginning, and earlier I was able to receive push notifications. (June was the last time I had tested Push-notifications; app is still in development) Now nothing is shown on device.

Also, push-notifications through cloudCode are sent successfully but have 0 recipients,ie, there is no error message, the success function is called Push notifications from the online dashboard also are sent but 0-recipients.

Edit2: Upgraded library to 1.13.1 ; Still no change.

summers314 commented 7 years ago

Application.java file:

import android.util.Log;

import com.parse.Parse;
import com.parse.ParseAnalytics;
import com.parse.ParseException;
import com.parse.ParseInstallation;
import com.parse.ParsePush;
import com.parse.ParseUser;
import com.parse.SaveCallback;

public class Application extends android.app.Application 
{

    private final String TAG = "ACTIVITY_APPLICATION";

  public Application() 
  {
  }

  @Override
  public void onCreate() 
  {
    super.onCreate();

    // Initialize the Parse SDK
    // Required to use Parse
    Parse.initialize(this, "", "");

    if(ParseUser.getCurrentUser() != null)
    {
        ParseInstallation.getCurrentInstallation().put("user", ParseUser.getCurrentUser());
        ParseInstallation.getCurrentInstallation().put("username", ParseUser.getCurrentUser().getUsername());
        ParseInstallation.getCurrentInstallation().saveInBackground(new SaveCallback() 
        {

            @Override
            public void done(ParseException e) 
            {
                if(e==null)
                {
                    Log.i(TAG, "SUCCESS|Length: Push");

                }else
                {
                    Log.i(TAG, "Length:" + "Error" );
                    Log.i(TAG, "Length:" + Integer.toString(e.getCode()) );
                    Log.i(TAG, "Length:" + e.getMessage() );
                }
            }
        });
    }

    ParsePush.subscribeInBackground("", new SaveCallback() 
    {
      @Override
      public void done(ParseException e) {
        if (e == null) {
          Log.d(TAG, "successfully subscribed to the broadcast channel.");
        } else {
          Log.e(TAG, "failed to subscribe for push", e);
        }
      }
    });

    ParseAnalytics.trackAppOpenedInBackground(null);
  }

}`

Everytime I start the app; the following log is recorded Log.d(TAG, "successfully subscribed to the broadcast channel."); ; which is for ParsePush.subscribeInBackground when e==null

summers314 commented 7 years ago

Manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
     ..
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="23" />

    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

    <!-- permission required to use Alarm Manager -->
    <uses-permission android:name="com.android.alarm.permission.SET_ALARM" />

    <!-- permission required for Notification -->
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />

    <!-- permission required to Send SMS -->
    <uses-permission android:name="android.permission.SEND_SMS" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

    <!-- permission required to get Location & Number -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

    <!-- permission required to Vibrate -->
    <uses-permission android:name="android.permission.VIBRATE" />

    <!-- permission required to Show Overlay -->
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

    <!-- permission required to use Parse -->
    <uses-permission android:name="android.permission.INTERNET" />

    <!-- permission required to use Parse Push -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

    <permission
        android:name="com.parse.starter.permission.C2D_MESSAGE"
        android:protectionLevel="signature" />

    <uses-permission android:name="com.hellboy.beat.permission.C2D_MESSAGE" />

    <application
        android:name="com.hellboy.beat.Application"
        android:allowBackup="true"
        android:hardwareAccelerated="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:largeHeap="true"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.hellboy.beat.Activity_check"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.hellboy.beat.main.Activity_main"
            android:launchMode="singleTask" />
        <activity android:name="com.hellboy.beat.login.Activity_login" />
        <activity
            android:name="com.hellboy.beat.requests.Activity_requests"
            android:launchMode="singleTask" />
        <activity android:name="com.hellboy.beat.settings.Activity_settings" />
        <activity android:name="com.hellboy.beat.frienddetails.Activity_frienddetail" />
        <activity android:name="com.hellboy.beat.frienddetails.friendlist.Activity_friendlist" />

        <!-- Share Overlay Activity -->
        <activity
            android:name="com.hellboy.beat.shareintent.Activity_shareintent"
            android:theme="@style/Theme.ShareOverlayTheme" >
            <intent-filter>
                <action android:name="android.intent.action.SEND" />

                <category android:name="android.intent.category.DEFAULT" />

                <data android:mimeType="text/plain" />
            </intent-filter>
        </activity>

        <receiver android:name="com.hellboy.beat.shareintent.Broadcast_shareintent" >
        </receiver>

        <service android:name="com.hellboy.beat.shareintent.Service_shareintent" />
        <service
            android:name="com.hellboy.beat.Service_StatusDone"
            android:process=".statusDoneService" />

        <!-- Register the Notification Receiver -->
        <service android:name="com.parse.PushService" />

        <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>
        <receiver android:name="com.hellboy.beat.PushRec" >
            <intent-filter>
                <action android:name="com.hellboy.beat.REQUEST_ACCEPT" />
                <action android:name="com.hellboy.beat.REQUEST_RECEIVE" />
                <action android:name="com.hellboy.beat.STATUS_DONE" />
                <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" />

                <!-- IMPORTANT: Change "com.parse.starter" to match your app's package name. -->
                <category android:name="com.hellboy.beat" />
            </intent-filter>
        </receiver>
    </application>

</manifest>

PushRec.java

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;

import org.json.JSONException;
import org.json.JSONObject;

import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;
import android.util.Log;

import com.beatinc.beatnews.R;
import com.hellboy.beat.main.Activity_main;
import com.hellboy.beat.requests.Activity_requests;
import com.parse.ParseException;
import com.parse.ParseObject;
import com.parse.ParseUser;
import com.parse.SaveCallback;

public class PushRec extends BroadcastReceiver
{
    private static final String TAG = "BEAT_PUSHREC";

    Context context;

    @Override
    public void onReceive(Context context, Intent intent) 
    {
        this.context = context;

        Log.i(TAG, "Receiver");

        if (intent == null)
        {
            Log.i(TAG, "Receiver intent null");
        }else
        {
            Log.i(TAG, "Receiver intent not null");

            String action = intent.getAction();
            Log.i(TAG, "got action " + action );

            if( action.equals("com.hellboy.beat.REQUEST_ACCEPT") )
                    {
                        .....

When I start the app the following logs are recorded:

Receiver

Receiver intent not null

got action android.intent.action.USER_PRESENT

summers314 commented 7 years ago

@grantland Is there anything you'd like me to provide specifically?

Does it have something to do with this? @inlined

https://github.com/ParsePlatform/Parse-SDK-Android/pull/452

Pkmmte commented 7 years ago

@summers314 This may sound stupid, but does it work after specifying a notification icon in your manifest?

<meta-data android:name="com.parse.push.notification_icon" android:resource="@mipmap/ic_notification_small"/>

I ran into this exact issue a few weeks ago. I didn't specify a notification icon because I was building my own notifications from a custom receiver. For some reason, it suddenly started working after adding this to my manifest, even if it's not being used.

lxknvlk commented 7 years ago

@Pkmmte btw for new androids the icon should be white&transparent png, but this wont affect anything most likely

summers314 commented 7 years ago

@Pkmmte That doesn't solve it either. In your installation class, does it show 'undefined' under the "pushType" & "deviceToken" column? Earlier this year it should gcm-under pushType & a string value under deviceToken. Should be an error with how I'm registering the Installation class in the Application.java file or something in the manifest? I've shared my manifest.xml file above

I doubt the if the error is on the client side, because when I send a PushNotification from the web-panel it shows 0-sent. Had it been a client side error it wouldn've sent it from the server side.

This is how I register Push and Installation in my Application.java class ; has this approach been changed?


     ParseInstallation.getCurrentInstallation().saveInBackground(new SaveCallback() 
     {

            @Override
            public void done(ParseException e) 
            {
                if(e==null)
                {
                    Log.i(TAG, "SUCCESS|Length: Push");

                }else
                {
                    Log.i(TAG, "Length:" + "Error" );
                    Log.i(TAG, "Length:" + Integer.toString(e.getCode()) );
                    Log.i(TAG, "Length:" + e.getMessage() );
                }
            }
        });
    }

    ParsePush.subscribeInBackground("", new SaveCallback() 
    {
      @Override
      public void done(ParseException e) {
        if (e == null) {
          Log.d(TAG, "successfully subscribed to the broadcast channel.");
        } else {
          Log.e(TAG, "failed to subscribe for push", e);
        }
      }
    });
inlined commented 7 years ago

Sorry for the late reply. FCM and GCM Sender IDs are the same thing (your Google Cloud project #), so I can't see that being the problem. My linked change was originally intended to help Parse upgrade to be compatible with Google's upcoming features before I could tell anyone that they were coming. The change did include a few bugfixes that never got patched in AFAIK--e.g. including setting the senderID on the Installation object--but their absence shouldn't introduce this aggressive a bug. Without that change's bugfixes Parse.com keeps sending messages using its own server key. That might mess up a few stats, but shouldn't affect your ability to send messages.

Now that Firebase Cloud Messaging is public and the new auto-init APIs are available, the real fix (for v4 incompatibility) is to rip out most of the Parse Android SDK code for registering for pushes. The Parse SDK should stop using undocumented APIs for GCM v3, which aren't compatible with [F|G]CM topics or Firebase Notifications. Instead, it should follow the FCM getting started guide.

My change was rejected for two primary reasons:

  1. The Parse team does not want a hard dependency on GMSCore. Even though GMSCore is much smaller than it used to be, it still increases the binary (and DEX) size of apps that don't use Parse Push.
  2. GCM v4 (and thus FCM) changes the way multiple-sender registration works. In v3, a single token could be minted that works with two different sender IDs. In v4, registration for multiple sender IDs results in multiple InstanceIDs. The ParseInstallation schema isn't designed to handle this and there's not a lot of point adding it to Parse now. Parse.com is the only service that really needs multiple sender IDs and it's deprecated. The only reasonable way to upgrade to v4 before the Parse shutdown is to change the behavior of registration with a custom sender ID so that devices registered with custom IDs don't work with the Parse sender ID.

After some thought, I've come up with a solution to (1): The SDK can add the com.google.firebase.INSTANCE_ID_EVENT intent to the ParseBroadcastReceiver's intent filter. Though recommended best practice is to use the FCM library to get the InstanceId, I believe the intent has a "registration_id" extra[1] that they can use instead of directly implementing the FirebaseInstanceIdService. The BroadcastReceiver would then set the installation ID as the deviceToken on the current Installation.

This would avoid a compile-time dependency on GMSCore, cut out lots of Parse code, and let ParsePush be compatible with newer features of FCM. I'd be curious whether keepers of the SDK (e.g. @grantland) are for this. Unfortunately, my last change took a lot of time and I just don't have the free cycles anymore. Someone else would have to pick up the charge.

[1]: One small tip. If I recall my hacking from 6mo ago correctly, the "registration_id" extra had an extra prefix that was an index followed by the pipe (|) character. This is due to the change in behavior where multiple sender IDs result in multiple FCM InstallationIDs. Chop off everything up to (and including) the pipe character and you'll have a valid Installation ID.

summers314 commented 7 years ago

Hi @inlined ! Thanks for replying.

In my case I have a valid installationID. However, under pushType& deviceTokenit shows undefined; where previously it had a string (eg: APA91bETlRdCtLd9o-SpReI86avXrYwg5eYI12QFqxYMpXl8XxPS5FsHwY0jCRuSlfpUZQWJmqUOjdZfdag2A04LRKJsy1N4VyOhbZzE5DHQg00c9A7K4VPSiRebzfetvasz-z3ubbRQ) and gcm, in the respective columns.

My recent installation objects have undefinedwritten under these two columns. I haven't updated my Android (5.0.2) since when it was working. So I suppose its either a Google/GCM issue or Parse SDK issue?

Since you mentioned that:

Without that change's bugfixes Parse.com keeps sending messages using its own server key. That might mess up a few stats, but shouldn't affect your ability to send messages.

But in the Installation class on Parse I have two columns that show undefined; is it safe to assume that the issue is with the Parse SDK and how it registers the Installation object? Maybe the way it had done it previously isn't compatible anymore ?

inlined commented 7 years ago

Hmm. It's possible. The part of Android that handles push notifications is in Google Mobile Services, not the core OS. This means you get updates whether or not you upgrade Android.

If you're not getting pushType or devideToken it sounds like something is failing in the SDK. Try calling Parse.setLogLevel(Parse.LOG_LEVEL_VERBOSE) in your Application (not Activity) onCreate

summers314 commented 7 years ago

@inlined Thanks a lot! Turns out, I'd changed the package name but that didn't reflect throughout other parts of the manifest which caused pushType and deviceToken to be 'undefined' . Would never have caught it if you'd not mentioned the above method (didn't know it existed either, thought parse displayed all errors/warnings/failures by default).

Thanks again!!

parse-github-bot commented 7 years ago

This issue has not been updated for 7 days. If you have additional information to help pinpoint this issue as an SDK bug, please comment on this issue. We will close this issue in 7 days if no additional information is provided. Thank you for your feedback.

natario1 commented 7 years ago

I really wish we would stay up to date with FCM, up to date with LiveQuery etc. It’s sad to see this SDK in a stale state. I can see much more activity and enthusiasm in parse-server and other parse SDKs. With all respect, maintainers here seem to be very busy with something else, but also restrictive on what to merge, while this SDK is far from complete and bug-free. And with parse-server implementing new features each week, it will be hard to ever get at par again.

summers314 commented 7 years ago

I've decided to move on to firebase finally :( I'm a front end dev, hosting a Parse-Server maintaining it all seems like a lot of effort with a lot of room for mistakes.

parse-github-bot commented 7 years ago

This issue has not been updated for 7 days. If you have additional information to help pinpoint this issue as an SDK bug, please comment on this issue. We will close this issue in 7 days if no additional information is provided. Thank you for your feedback.

parse-github-bot commented 7 years ago

We are closing this issue due to another 7 days of inactivity. If you have additional information to help pinpoint this issue as an SDK bug, please reopen it with the additional information.Thank you for your feedback.

anilbarnwal commented 7 years ago

If anyone is still facing this problem, please find solution here:

http://stackoverflow.com/questions/33293284/parse-error-for-updating-devicetoken-in-installation-table/41313844#41313844

Attached library is having deviceToken editable.