Android Push Registration Crashes App

Hi,
I’ve tried to implement Backendless Push Services to my Android app but it occasionally ( 2-3 out of 10 times, roughly) crashes the app at the stage of initial registration.
My concern isn’t why registration fails, rather the app works and opens.
If it couldn’t register, then let it be; whenever it finds the opportunity, it’ll register the device and starts to receive push notifications.
Unfortunately, it isn’t the story in my case.
Before the code samples and details, I’d like to ask that should I call the Backendless.Messaging.registerDevice() function every time the app starts as the Backendless.initApp() or should I check the registration status and register if and only it needs?
Ok, details…
This fails and crashes the app:

Backendless.Messaging.registerDevice( ArkConstants.gcmSenderID );

This, too, fails and crashes the app because somehow the exception thrown cannot be catch:

try { 


Backendless.Messaging.registerDevice( ArkConstants.gcmSenderID ); 


} catch ( Exception e ) { e.printStackTrace(); }

And this, also, fails and the error / exception cannot be caught in the handleFault():

Backendless.Messaging.registerDevice( ArkConstants.gcmSenderID, null, new AsyncCallback<Void>() { 


@Override 
public void handleResponse ( Void response ) {} 


@Override 
public void handleFault(BackendlessFault fault) {
Log.v("kpTag", fault.getCode() );
Log.v("kpTag", fault.getMessage() );
Log.v("kpTag", fault.getDetail() );
} 


});

Tried to throw a RuntimeException myself and it’s getting caught:

try { 


throwAnErrorForMe(); 


} catch ( Exception e ) { e.printStackTrace(); } 


private void throwAnErrorForMe () { 


throw new RuntimeException( "A Sample RuntimeException" ); 


}

As I’ve stated above, I don’t care much for the reasons of failure; what I want is that the service fails gracefully and do not crash my app completely.
But still, here are two logs of the many different errors:


E/AndroidRuntime: FATAL EXCEPTION: IntentService[BackendlessPushService]
 Process: com.kqapius.SAMPLEAPP, PID: 2397
 java.lang.RuntimeException: AUTHENTICATION_FAILED
 at com.backendless.push.BackendlessPushService.onError(BackendlessPushService.java:88)
 at com.backendless.push.BackendlessPushService.handleRegistration(BackendlessPushService.java:233)
 at com.backendless.push.BackendlessPushService.handleIntent(BackendlessPushService.java:98)
 at com.backendless.push.BackendlessPushService.onHandleIntent(BackendlessPushService.java:65)
 at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:67)
 at android.os.Handler.dispatchMessage(Handler.java:102)
 at android.os.Looper.loop(Looper.java:154)
 at android.os.HandlerThread.run(HandlerThread.java:61)






E/AndroidRuntime: FATAL EXCEPTION: main
 Process: com.kqapius.SAMPLEAPP, PID: 9337
 java.lang.RuntimeException: Could not register device on Backendless server: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Can't call rollback when autocommit=true
 at com.backendless.push.BackendlessPushService.onError(BackendlessPushService.java:88)
 at com.backendless.push.BackendlessPushService$1.handleFault(BackendlessPushService.java:252)
 at com.backendless.Messaging$2.handleFault(Messaging.java:247)
 at com.backendless.async.message.AsyncMessage$FaultHandler.handle(AsyncMessage.java:83)
 at com.backendless.async.message.AsyncMessage.handleCallback(AsyncMessage.java:41)
 at com.backendless.core.AndroidCarrier$1.handleMessage(AndroidCarrier.java:37)
 at android.os.Handler.dispatchMessage(Handler.java:98)
 at android.os.Looper.loop(Looper.java:168)
 at android.app.ActivityThread.main(ActivityThread.java:5845)
 at java.lang.reflect.Method.invoke(Native Method)
 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797)
 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:687)

Please find the code of main activity of my app attached including the push registration logic.
Thanks,
~ Fatih

BaseApplication.txt (2.16kB)

This comment is not directly relevant to the problem, I’m well aware of that; and it’s falling 'little bit into the category of whining.
I was in a very tight schedule and because of some other issues with the Backendless Data Services, I’ve way passed the deadline.
Then I gave up and put together a little php ( with my limited php knowledge ) and created a micro-webservice a couple of days ago, which works without a problem. Push, of course, was in the hands of Backendless.
And I was hoping to publish the app, today.

But hey, humans make plans and Gods laugh, huh?
I’m still going to publish but without a Push Notification functionality until I find a solution. Thanks to heavens, Play Store doesn’t have a Review process as App Store.

Best,

~ Fatih

P.S.
Just to make clear of “some other issues”, mainly performance and inconsistencies. Fetching 10 to 20 contact info can take more than 10 seconds sometimes, whereas a simple LAMP stack, which has been put together in a matter of hours, can query, organize and then provide more than 3000 objects ( people, sessions, bulletins, etc. ) in under 2 seconds. And it’s consistent as I can see same results at more than 100 tests. Backendless was throwing errors, returning empty arrays, returning different results for same queries, etc. etc.

There’s a reason for this is a comment and not a question or problem, btw.
I couldn’t find time to diagnose the issues and provide you a well-structured problem backed with logs and test results. Later, perhaps.

Hi Fatih,

Internal ticket with id BKNDLSS-13238 has been created for this issue.

Regards,

Denys

Thanks Denys…

Hi Faith,
Please look at our push sample as an example at https://github.com/Backendless/Android-SDK/tree/master/samples/MessagingService/pushdemo
Also please read docs about Backendless push service at https://github.com/Backendless/Android-SDK/blob/master/docs/push.md and the section how to obtain GCM tokens at https://backendless.com/documentation/messaging/android/messaging_push_notification_setup_androi.htm.
This should be helpful.
Artur

Hi Arthur,

I’m not sure that I understand.
Are you saying that this is not a bug or something rather a programmer mistake?
If so, why did you assigned it to a dev?
And how would you explain that the exception not getting caught, which is my main problem, I want my app not crash?
And how are those error descriptions related to GCM tokens?

Really, it doesn’t make much sense.
But still, if you’re sure that it’s a coding mistake, then ok, I can check again.
Although there isn’t much code to check. Just a simple registration call which fails and crashes the app, I can’t see where I could have made a mistake:

try {

Backendless.Messaging.registerDevice( ArkConstants.gcmSenderID );

} catch ( Exception e ) { e.printStackTrace(); }

Best,

~ Fatih

Hi Faith,
Your app crashes because default implementation of PushService::onError throws RuntimeException. You can check it at https://github.com/Backendless/Android-SDK/blob/master/src/com/backendless/push/BackendlessPushService.java#L88.
To resolve the issue you need to override default implementation of onError() method (not calling super of course).
Artur

Hi Arthur,

You said that “PushService::onError throws RuntimeException”
That is indeed my question, why the exception is not getting caught and does crash my app, especially given that I’m encapsulating the related command within a try-catch block?

Anyways, I did what you’ve suggested as overriding the default implementation and not calling super.

Here is the result:


E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: com.kqapius.clientCode.AppName, PID: 16117
                  java.lang.RuntimeException: Could not register device on Backendless server: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Can't call rollback when autocommit=true
                      at com.backendless.push.BackendlessPushService.onError(BackendlessPushService.java:88)
                      at com.backendless.push.BackendlessPushService$1.handleFault(BackendlessPushService.java:252)
                      at com.backendless.Messaging$2.handleFault(Messaging.java:247)
                      at com.backendless.async.message.AsyncMessage$FaultHandler.handle(AsyncMessage.java:83)
                      at com.backendless.async.message.AsyncMessage.handleCallback(AsyncMessage.java:41)
                      at com.backendless.core.AndroidCarrier$1.handleMessage(AndroidCarrier.java:37)
                      at android.os.Handler.dispatchMessage(Handler.java:98)
                      at android.os.Looper.loop(Looper.java:168)
                      at android.app.ActivityThread.main(ActivityThread.java:5845)
                      at java.lang.reflect.Method.invoke(Native Method)
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:687)

And here’s my overriding code:


@Override
public void onError( Context context, String message )
{
    Log.v("rnfTag", message );


}

When I change the above overriding code to the following:


@Override
public void onError( Context context, String message )
{
    throw new RuntimeException( message );
}

then I get this error and of course the app’s still crashing:


E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: com.kqapius.clientCode.AppName, PID: 14708
                  java.lang.RuntimeException: Could not register device on Backendless server: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Can't call rollback when autocommit=true
                      at com.kqapius.clientCode.AppName.receiver.KPBackendlessPushService.onError(KPBackendlessPushService.java:43)
                      at com.backendless.push.BackendlessPushService$1.handleFault(BackendlessPushService.java:252)
                      at com.backendless.Messaging$2.handleFault(Messaging.java:247)
                      at com.backendless.async.message.AsyncMessage$FaultHandler.handle(AsyncMessage.java:83)
                      at com.backendless.async.message.AsyncMessage.handleCallback(AsyncMessage.java:41)
                      at com.backendless.core.AndroidCarrier$1.handleMessage(AndroidCarrier.java:37)
                      at android.os.Handler.dispatchMessage(Handler.java:98)
                      at android.os.Looper.loop(Looper.java:168)
                      at android.app.ActivityThread.main(ActivityThread.java:5845)
                      at java.lang.reflect.Method.invoke(Native Method)
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:687)

The thing is, it’s not doing that all the time. 2 - 3 times out of 10 perhaps.

And as a follow-up issue; when it manages to register the device, it creates duplicates.
I have multiple Android devices now in Dashboard -> Messaging -> Devices with completely identical DeviceIDs and Device Tokens.

My app is alive and clients already started to download it.
Thus, I’m a little desperate here…

~ Fatih

We will look into this issue, as a temporary solution what about re-trying registering device if registration fails?
Artur

Hi Arthur,

When the registration fails, the app crashes which means it’s no longer alive, bang bang boom.
My very problem is this.
I just want my app doesn’t crash.
That’s it, nothing more nothing less.

I can always re-register it in case of failure as you’ve kindly suggested but that’s not the case.

A function ( Backendless.Messaging.registerDevice() or others alike ) encapsulated within try-catch block completely crashes the app.
I have no idea why and how it can produce a non-catchable exception, but it does.

So, re-registering is not an option for me because my app simply cannot get that opportunity.

Best,

~ Fatih

You have posted stack trace above, where it is obvious that your app has crashed in method com.backendless.push.BackendlessPushService.onError

E/AndroidRuntime: FATAL EXCEPTION: IntentService[BackendlessPushService]
 Process: com.kqapius.SAMPLEAPP, PID: 2397
 java.lang.RuntimeException: AUTHENTICATION_FAILED
 at com.backendless.push.BackendlessPushService.onError(BackendlessPushService.java:88)
 at com.backendless.push.BackendlessPushService.handleRegistration(BackendlessPushService.java:233)
 at com.backendless.push.BackendlessPushService.handleIntent(BackendlessPushService.java:98)
 at com.backendless.push.BackendlessPushService.onHandleIntent(BackendlessPushService.java:65)
 at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:67)
 at android.os.Handler.dispatchMessage(Handler.java:102)
 at android.os.Looper.loop(Looper.java:154)
 at android.os.HandlerThread.run(HandlerThread.java:61)

You can override it not to throw the exception and your app will not crash. Anyway, we made some changes in SDK and in future versions method onError will not throw exception but just write to log and display a toast.
Artur

Linked pull request on Github https://github.com/Backendless/Android-SDK/pull/252/commits/2d5defcf2568257990cd2a4123795029cddb39de#diff-2d17d17fea8f0b240c7b7200d925b8f4R87

Hi Arthur,

First, thanks for all your effort and time.

Second, I already did that; I mean “not throwing an exception”.

If you look at my previous comment you’ll see that my first try was overriding as:

@Override
public void onError( Context context, String message )
{
Log.v("rnfTag", message );

}

That made the Backendless throw the exception and crashes the app, which means then overriding doesn’t work as expected somehow.
So, problem might be deeper than it seems and the solution might require more than simply putting a console log.
Just my two cents, of course.
Maybe, that change in the linked pull request will solve the problem.

Let’s wait and test to see the results.

Thanks again…

Best,

~ Fatih

Here it is:
KPBackendlessPushService.java

Could you please share your custom BroadcastReceiver and a manifest file

Receiver:
KPBackendlessPushReceiver

and the manifest:
AndroidManifest

Btw, I’ve hidden the Google API Key and changed the app/client name because of NDA thing.

My AndroidManifest has the real api key, it’s not a typo or something.

Please remove this lines
<receiver android:name=“com.backendless.push.BackendlessBroadcastReceiver”

                android:permission="com.google.android.c2dm.permission.SEND">
  
  
                &lt;intent-filter&gt;
  
  
                    <action android:name="com.google.android.c2dm.intent.RECEIVE"/>
  
  
                    <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
  
  
    


  
  
                    &lt;category android:name=&quot;com.developer.client.APPNAME&quot;/&gt;
  
  
                &lt;/intent-filter&gt;
  
  
            &lt;/receiver&gt;
  
  
            &lt;service android:name=&quot;com.backendless.push.BackendlessPushService&quot; /&gt;

Thank you Arthur,
I can’t believe that it finally turned out to be my mistake :confused:

176 tests and not a crash, not an error, not a failure to register, nothing, all success.
Moreover, the duplicate entry issue is gone; too.
Single device, single registration in the dashboard.

Thanks again.

Btw, the app doesn’t get push notifications at all.
But that’s clearly my fault.
I’m gonna check the documentation once more and see if there’s anything I should’ve done.
If you did see any clear mistake in those gists, I’d be happy if you could tell.
If not, no worries; I know that you don’t give this kind of support in free tier.

Regards,

~ Fatih

Hello Arthur,

I am also getting the same exception using the latest SDK, I have re-verified the implementation and everything is according to the documentation.
public class MyApplication extends Application {

@Override
public void onCreate() {
    super.onCreate();
    Backendless.initApp(this, "xxxxxxxxxxxxxxx", "xxxxxxxxxxxxxx", "v1");

    try {
        Backendless.Messaging.registerDevice("xxxxxxxxxxx", new AsyncCallback&lt;Void&gt;() {
            @Override
            public void handleResponse(Void response) {
                // Device Registered Successfully
            }
            @Override
            public void handleFault(BackendlessFault fault) {
                // Device Not Registered Error
            }
        });
    } catch (Exception excep) {
        Log.d("MyApplication", excep.getMessage());
    }
}


<intent-filter>

    &lt;category android:name=&quot;com.thebestlivete.pkdintdpoe&quot; /&gt;
&lt;/intent-filter&gt;

</receiver>
<service android:name="com.backendless.push.BackendlessPushService" />

Fatal Exception: java.lang.RuntimeException: Could not register device on Backendless server: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Can’t call rollback when autocommit=true
at com.backendless.push.BackendlessPushService.onError(BackendlessPushService.java:88)
at com.backendless.push.BackendlessPushService$1.handleFault(BackendlessPushService.java:252)
at com.backendless.Messaging$2.handleFault(Messaging.java:247)
at com.backendless.async.message.AsyncMessage$FaultHandler.handle(AsyncMessage.java:83)
at com.backendless.async.message.AsyncMessage.handleCallback(AsyncMessage.java:41)
at com.backendless.core.AndroidCarrier$1.handleMessage(AndroidCarrier.java:37)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5299)
at java.lang.reflect.Method.invokeNative(Method.java)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:932)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:748)
at dalvik.system.NativeStart.main(NativeStart.java)

Regards
Raza