chemerisuk / cordova-plugin-firebase-messaging

Cordova plugin for Firebase Cloud Messaging
MIT License
164 stars 159 forks source link

plugin methods do not respond in Android 7 #135

Closed scottlikestech closed 11 months ago

scottlikestech commented 4 years ago

This applies to all methods; getToken(), getInstanceId(), requestPermission(), etc.

I have 4 Android devices. Same code on Android 9 phone and Android 10 tablet works fine. I get the token, etc.
But my 2 other devices are running Android 7 (a Samsung Galaxy and a CUBOT King) and none of the methods return their promises.

It's not completely broke on the Android 7 because if I log into my Firebase account and send a message to all users based on the app ID, all 4 devices will receive and show the notification.

But because the plugin methods on Android 7 don't return, I can't get a token from these devices and then just send messages to these devices.

I am not setting the channel id on the messages to anything specific so they all use the "default" one embedded in the manifest and the other 2 devices on Android 9 and 10 are fine.

AlibekJ commented 4 years ago

The same issue in similar conditions, Android 7.1.1

 17479 17654 W System.err: java.lang.NoClassDefFoundError: android.app.NotificationChannel
 17479 17654 W System.err:  at libcore.reflect.InternalNames.getClass(InternalNames.java:55)
 17479 17654 W System.err:  at java.lang.Class.getDexCacheType(Class.java:2551)
 17479 17654 W System.err:  at java.lang.reflect.AbstractMethod.getParameterTypes(AbstractMethod.java:169)
 17479 17654 W System.err:  at java.lang.reflect.Method.getParameterTypes(Method.java:193)
 17479 17654 W System.err:  at java.lang.Class.getDeclaredMethods(Class.java:1812)
 17479 17654 W System.err:  at by.chemerisuk.cordova.support.ReflectiveCordovaPlugin.createCommandFactories(ReflectiveCordovaPlugin.java:70)
 17479 17654 W System.err:  at by.chemerisuk.cordova.support.ReflectiveCordovaPlugin.execute(ReflectiveCordovaPlugin.java:28)
 17479 17654 W System.err:  at org.apache.cordova.CordovaPlugin.execute(CordovaPlugin.java:98)
 17479 17654 W System.err:  at org.apache.cordova.PluginManager.exec(PluginManager.java:132)
 17479 17654 W System.err:  at org.apache.cordova.CordovaBridge.jsExec(CordovaBridge.java:59)
 17479 17654 W System.err:  at org.apache.cordova.engine.SystemExposedJsApi.exec(SystemExposedJsApi.java:41)
 17479 17654 W System.err:  at android.os.MessageQueue.nativePollOnce(Native Method)
 17479 17654 W System.err:  at android.os.MessageQueue.next(MessageQueue.java:331)
 17479 17654 W System.err:  at android.os.Looper.loop(Looper.java:219)
 17479 17654 W System.err:  at android.os.HandlerThread.run(HandlerThread.java:61)
 17479 17654 W System.err: Caused by: java.lang.ClassNotFoundException: Didn't find class "android.app.NotificationChannel" on path: DexPathList[[zip file "/data/app/com.myapp.www-1/base.apk"],nativeLibraryDirectories=[/data/app/com.myapp.www-1/lib/arm64, /data/app/com.myapp.www-1/base.apk!/lib/arm64-v8a, /system/lib64, /vendor/lib64]]
 17479 17654 W System.err:  at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
 17479 17654 W System.err:  at java.lang.ClassLoader.loadClass(ClassLoader.java:380)
 17479 17654 W System.err:  at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
 17479 17654 W System.err:  at libcore.reflect.InternalNames.getClass(InternalNames.java:53)
 17479 17654 W System.err:  ... 14 more
chemerisuk commented 4 years ago

What is your compile/target SDK? android.app.NotificationChannel is a system class and should be available in class path.

scottlikestech commented 4 years ago

As taken from the project.properties file, target=android-28 Perhaps my error is not the same as AlibekJ. My exposure to native code is not so great.

It is a cordova project using cordova version 9, Android engine 8.1.0 with the following plugins installed:

cordova-plugin-firebase-messaging cordova-plugin-firebase-analytics cordova-support-android-plugin (reference of plugins above) cordova-support-google-services (reference of plugins above)

Just like other plugins, no attempt is made to use your plugin methods until after the $ionicPlatform.ready event has fired. And for my Android 9 and 10 devices, all the methods return their promises and messages sent to their tokens work. My two Android 7 devices get nothing back from any method, but will still receive a notification from the firebase console website that allows you to not specify the sender token.

scottlikestech commented 4 years ago

I got hold of another Android device running Android 7.0 and have the same issue as the other two Android 7 devices. This one is a HUAWEI, model BAH-W09. My 2 other devices running Android 7 are a Samsung Galaxy and a CUBOT King. Far less concerned about the CUBOT King. None of the methods return their promises on these devices.

th3hamm0r commented 4 years ago

I'm having the same issues (both debug and release builds). It seems like it has something to do with the used reflection (@CordovaMethod) in combination with multidex and pre-dex. Multidex is on by default in minSdkVersion >= 21 and pre-dexing is used by the built tools in debug mode (see https://developer.android.com/studio/build/multidex). I've tried several options like multiDexKeepFile (to keep the Notification class in the main dex) or preDexLibraries to avoid the error, but none of them succeeded. Finally, when I replaced all the usages of @CordovaMethod with a custom coded execute(...)-method, the error has gone and the plugin works again.

@chemerisuk I would recommend to remove the reflection based annotations. Although it requires some boilerplate code (in this case not that much), it avoids typical issues with minification or in the above case with missing class info in the main dex file.

scottlikestech commented 4 years ago

@th3hamm0r - really good news you got it to work. What is the exact change you made to the file?

chemerisuk commented 4 years ago

I use several plugins with @CordovaMethod on prod with many different Android devices. So far no complains that methods do not work.

th3hamm0r commented 4 years ago

@scottlikestech I've pasted its contents into a gist https://gist.github.com/th3hamm0r/c6806e97e3d708ba51fae0b70d3ab7a4 But note, that this was only a quick-and-dirty approach for a prototype app I've needed, so beside simple foreground and background pushes, I have not tested it.

@chemerisuk Have you used it in apps with a minSdkVersion of 21 (I think cordova is at 19)? Another possible difference of our app to a normal cordova app is that we use R8 for code shrinking (useProguard false in gradle). This will be the default with the new Android Gradle plugin 3.4.0 (cordova is at 3.3.0). I'm just trying to find some possible issues, but with increasing number of used cordova plugins, it's always getting harder.

chemerisuk commented 4 years ago

@th3hamm0r have you read https://github.com/chemerisuk/cordova-support-android-plugin#proguard-notes? For proguard you need to add extra rules. It can be cause of the problem.

th3hamm0r commented 4 years ago

@chemerisuk good point, haven't read that, but I think this won't solve the issue for the debug build.

edit: unfortunately I still get the java.lang.NoClassDefFoundError: android.app.NotificationChannel, in both the debug and the release build.

chemerisuk commented 4 years ago

@th3hamm0r what is your target sdk? android.app.NotificationChannel is a system class.

th3hamm0r commented 4 years ago

target sdk: 28 min sdk: 21 build tools: 29.0.2

chemerisuk commented 4 years ago

@th3hamm0r can you post a full build log?

scottlikestech commented 4 years ago

@th3hamm0r your replacement Java file worked for me. Both my Android 7 devices and Android 9/10 devices all return a token and receive the messages. I don't use the plugin extensively so I can only vouch for the getToken() method, but that's all I needed. Thanks :-)

jmouriz commented 4 years ago

@th3hamm0r can you post a full build log?

@chemerisuk android.app.NotificationChannel is a system class part of SDK, so the build has no errors but when run in Android 7 get the @AlibekJ output in logcat. I forked repo and disable NotificationChannel references and I get the token. NotificationChannel references are conditionals but fail the import. Could the solution be to build a dummy NotificationChannel class?

DiegoGarciaMartin commented 4 years ago

I have the same problem with a Android 7.1.1.

target sdk: 28 min sdk: 21 build tools: 29.0.3

Any solution¿?


Edit 1

I downgraded the version to the 4.1.1 (the previous to the channels implementation) and it works.

chemerisuk commented 4 years ago

@jmouriz @DiegoGarciaMartin what is your value for compileSdkVersion in app/build.gradle?

AlibekJ commented 4 years ago

In my case it is null.

DiegoGarciaMartin commented 4 years ago

@jmouriz @DiegoGarciaMartin what is your value for compileSdkVersion in app/build.gradle?

28

chemerisuk commented 4 years ago

Alright, I was able to reproduce and fix this issue. Problem was in method toJSON(NotificationChannel). This method used parameter type NotificationChannel which is available on Android 8+ only. It was the cause of why getDeclaredMethods in ReflectiveCordovaPlugin threw an exception.

chemerisuk commented 4 years ago

Bugfix published in v4.4.1, thanks everybody for the input.

pcsantana commented 4 years ago

Hello everyone! I know this is not a plug-in issue, but did anyone have a problem sending a push notification to Android 7 from own server? If I send from the firebase console, I get the notification. But if I send from my own server, only Android devices >= 8 receive the notification. I'm using the firebase server SDK, like this: https://firebase.google.com/docs/cloud-messaging/send-message?#send-messages-to-multiple-devices

Thank you in advance.

darkguy2008 commented 2 years ago

I'm also getting this right now with a 7.0 device and package version 6.1.1. This can also be reproduced in the emulator.

"@awesome-cordova-plugins/firebase-messaging": "^5.39.0",
"cordova-plugin-firebase-messaging": "^6.1.1",

Is there any known solution to this problem? No method runs and since my app depends on this plugin to get the firebase token, it just stays blank waiting for the method (or the promise) to resolve.

Thanks!

EDIT: Fixed it by downgrading to 4.4.1

S-AT commented 2 years ago

Bugfix published in v4.4.1, thanks everybody for the input.

@chemerisuk Maksim, should we downgrade to 4.4.1 in order to support Android 7? As the problem reproduces with 6.1.1

chemerisuk commented 2 years ago

@darkguy2008 @S-AT try to install 6.1.0 instead... I guess it's a regression after applying changes from https://github.com/chemerisuk/cordova-plugin-firebase-messaging/commit/334089904c7d7dc226a448321efdbcdad5bc2cd4.

This can also be reproduced in the emulator

What are steps to reproduce it on emulator?

S-AT commented 2 years ago

@chemerisuk Maksim, you're right! 6.1.0 works as expected.

chemerisuk commented 2 years ago

@S-AT do you mind to test if 6.1.2 works on your side?

S-AT commented 2 years ago

@S-AT do you mind to test if 6.1.2 works on your side?

@chemerisuk Maksim, thank you for the update! I've tested 6.1.2, the problem persists, unfortunately.

noriellecruz commented 2 years ago

was this already fixed in the latest release?

chemerisuk commented 1 year ago

@noriellecruz yes, should be fixed in the latest release because problematic method removed from source code.