A little over a year ago, I posted a two part article about integrating Firebase Cloud Messaging in your Delphi mobile apps. This time, it’s a single part article because much of the work is done for you, or is simplified.
The code in this article was built and tested using an install of the latest Delphi 10.2.3 (build 25.0.31059.3231), and at least for iOS, will require specifically this version. For Android you may be able to make it work in Delphi 10.1 Berlin or earlier.
TL;DR: The demo can be found here, bearing in mind that it requires other parts of KastriFree, and requires you to do a little configuration (see the Configuration section in this article)
Firebase SDK changes
There have been quite a number of releases since the original article, which used version 10.2.1 of the Firebase Android SDK, and version 4.3.0 of the Firebase iOS SDK. This article uses the latest released SDKs: the Firebase Messaging Android library is numbered 17.1.0 (libraries that it depends on have lower numbers) and the Firebase iOS SDK is at 5.5.0.
In the previous articles, it was up to the reader to download and extract the SDKs using the tools described in the articles. This time, I have uploaded the bare minimum libraries to the KastriFree project so that the demo project should just compile and run, after supplying a couple of files of your own.
Firebase Cloud Messaging (FCM) support changes
Due to changes in the SDKs, the supporting code has also changed. This means that the older demo will probably not compile, and will certainly not work using the older SDKs.
Support for later versions of iOS and Android
Some may have noticed that notifications (both local and remote) are not working as expected in later versions of iOS. In this solution, the device will display a push notification when the app is not running, when the app is in the background, and when in the foreground. This is because it makes use of the later APIs, including UNUserNotificationCenter which allows notifications to show in the foreground.
Similarly, if on Android you are targeting API 26 or greater (which is a requirement for Google Play apps), you may have noticed that both local and remote notifications do not show at all. This is due to the API 26 requirement of the use of notification channels. The FCM support in this solution makes use of these, so your notifications will show. This solution also makes use of TPermissionsRequester introduced in an article regarding targeting API 26 or greater, to demonstrate requesting “dangerous” permissions. The permissions being requested here are not actually required for this demo, so as per the comments in the code, you may remove the references to TPermissionsRequester if you do not require it.
Caveats
There is a known issue with linking to the Firebase iOS SDK when targeting some versions of the iOS SDK, namely iOS SDK 11.3 or later. It has also been reported that this is sometimes an issue with iOS 11.2 SDK, however it is not always the case. Hopefully this issue will be resolved in the next release of Delphi.
Configuration
As per the introduction above, much of the work this time has already been done for you. However there are two important aspects that you will need to take care of before the demo will work. In part 1 of the original article, once you have set up your Firebase Console project (for each platform you require), you will need to download google-services.json from the Android section, and GoogleService-info.plist from the iOS section.
- For iOS:Save GoogleService-info.plist into the Resources folder of the project. You don’t need to add it to the Project Deployment because it has already been added.As per section 2 of the second article, you will need to modify the CFBundleIdentifier value:As per section 3, add the following frameworks to the iOS SDK:AdSupport
AudioToolbox
AVKit
CoreAudio
CoreMIDI
ImageIO
IOSurface
MediaToolbox
Metal
SystemConfiguration
UserNotifications - For Android:As per section 3 of the first article, you will need to modify the package name value:Create a copy of strings.template.xml from the KastriFree project, open it in an editor, then insert values for each of the entries that correspond to the values from google-services.json:
and save the modified strings.template.xml as strings.xml, to the Resources folder of the demo.
You won’t need to do this for the demo, however for other projects you will need to add the required jars, and disable conflicting jars, as per this image:
As per the intro, the demo is here, and remember that it relies on files from KastriFree.
Hi Dave! I’m having trouble compiling. The following error is appearing
[DCC Error] DW.Firebase.InstanceId.Android.pas (67): E2003 Undeclared identifier: ‘TJDWFirebaseInstanceIdService’.
Can you tell me what I must be forgetting?
Best regards
If you’re compiling the latest demo as per the article, you should not be receiving that error at all. If you’re compiling an older project, make sure you remove DW.Firebase.InstanceId from any uses clauses; it is no longer required.
Hi Dave! On older version I can listen TokenRefresh by DW.Firebase.InstanceId. If isn’t longer required, Can I use TFirebaseMessaging.OnTokenReceived for RefreshedToken too?
Regards.
OnTokenReceived should fire every time the app starts regardless of whether or not the token has changed, and whenever the token changes. If you save the token somewhere (e.g. to a file), you can check if it has changed
Hi Dave!
Firstly, thanks for the post that has helped the whole community. Congratulations on the excellent work, sharing knowledge.
I made the implementations and am receiving the notifications when the application is open, but if the application is closed or in the background the notification does not arrive or it does not appear
What platform is this on? How are you sending the message, and what is the payload?
The problem occurs in Android 8.0. I am sending a test message from the Firebase console. Here is the payload I get when the app is open.
gcm.message_id = 0: 1534728175838413% f149c2bef149c2be
gcm.ttl = 86400
gcm.from = 182139549881
gcm.sent_time = 1534728175799
What happens if you send a message using the method described after section 10, here?:
http://delphiworlds.com/2017/05/add-firebase-cloud-messaging-mobile-apps-part-1/
I’m just sending a message titled “Test” and the content “Test” through the Firebase console.
By sending following the steps of section 10 the same problem occurs.
I read something about a similar problem, in which I would like to add the strings.xml file to the line ” default ” but I did not succeed.
If you send the same message to a device with android 6, it works normally.
I might have broken something.. I’ll check in a few hours
This is the feedback I have made through the method.
{
“multicast_id”: 7114813550938787445,
“success”: 1,
“failure”: 0,
“canonical_ids”: 0,
“results”: [
{
“message_id”: “0: 1534731345731812% f149c2bef149c2be”
}
]
}
The only thing I can see that may have changed was this file, which I have now rebuilt:
https://github.com/DelphiWorlds/KastriFree/blob/master/Lib/dw-firebase.jar
However, you may wish to check that your strings.xml (which you should have in the Resources folder in the demo) has the correct values.
Also, check that the Libraries under the Android platform in Project Manager match the last image in the article.
Hello Dave!
The problem persists even by updating the dw-firebase.jar file.
I do not know if it has anything to do but when the application is open and receives the notification, the notification icon comes completely blank. The application icon does not appear.
This only happens on Android 8. Previous versions of Android work perfectly.
I’ll keep trying. If so, put it in the comments.
Thank you Dave!
That’s very odd. Do you have Android 8.0, or 8.1? It all works OK on my Nexus 5X, which has 8.1
Android 8.0 Samsung S8 +
Hi, Dave. This is the monitor log. Do you have any tips that can help me?
09-04 19:55:07.502: W/Notification(13070): Use of stream types is deprecated for operations other than volume control
09-04 19:55:07.502: W/Notification(13070): See the documentation of setSound() for what to use instead with android.media.AudioAttributes to qualify your playback use case
09-04 19:55:07.546: W/FirebaseMessaging(13070): Unable to log event: analytics library is missing
09-04 19:55:07.610: W/FirebaseMessaging(13070): Notification Channel set in AndroidManifest.xml has not been created by the app. Default value will be used.
09-04 19:55:07.618: E/FirebaseMessaging(13070): Error while setting the notification channel
09-04 19:55:07.618: E/FirebaseMessaging(13070): java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/firebase/messaging/R$string;
09-04 19:55:07.618: E/FirebaseMessaging(13070): at com.google.firebase.messaging.zza.zzn(Unknown Source:195)
09-04 19:55:07.618: E/FirebaseMessaging(13070): at com.google.firebase.messaging.zza.zzh(Unknown Source:310)
09-04 19:55:07.618: E/FirebaseMessaging(13070): at com.google.firebase.messaging.FirebaseMessagingService.zzd(Unknown Source:261)
09-04 19:55:07.618: E/FirebaseMessaging(13070): at com.google.firebase.iid.zzg.run(Unknown Source:26)
09-04 19:55:07.618: E/FirebaseMessaging(13070): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
09-04 19:55:07.618: E/FirebaseMessaging(13070): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
09-04 19:55:07.618: E/FirebaseMessaging(13070): at com.google.android.gms.common.util.concurrent.zza.run(Unknown Source:7)
09-04 19:55:07.618: E/FirebaseMessaging(13070): at java.lang.Thread.run(Thread.java:764)
09-04 19:55:07.618: E/FirebaseMessaging(13070): Caused by: java.lang.ClassNotFoundException: Didn’t find class “com.google.firebase.messaging.R$string” on path: DexPathList[[zip file “/data/app/com.embarcadero.keepin-GVOXpZK5sAjXWhfzXj1fMg==/base.apk”],nativeLibraryDirectories=[/data/app/com.embarcadero.keepin-GVOXpZK5sAjXWhfzXj1fMg==/lib/arm, /data/app/com.embarcadero.keepin-GVOXpZK5sAjXWhfzXj1fMg==/base.apk!/lib/armeabi-v7a, /system/lib, /system/vendor/lib]]
09-04 19:55:07.618: E/FirebaseMessaging(13070): at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:93)
09-04 19:55:07.618: E/FirebaseMessaging(13070): at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
09-04 19:55:07.618: E/FirebaseMessaging(13070): at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
09-04 19:55:07.618: E/FirebaseMessaging(13070): … 8 more
Please make sure that the libraries in the “Libraries” node under the Android target in Project Manager match the last image in this article. In particular, you may be missing the one named: play-services-r-15.0.1.jar. Make sure that the icon next to it is a white rectangle, i.e. it should not have a red circle with a white “x” through it (meaning that it cannot be found)
The only exception I have is that if I disable google-analytics-v2.dex.jar my application hangs at startup.
actually hangs when I leave the cloud-messaging.dex.jar file disabled
Apparently Samsung are rolling out 8.1 this month?
https://www.gottabemobile.com/samsung-galaxy-android-8-1-update/
I strongly suggest you update, if you can
Same problem on Android 8.
Hi Dave!
First of all, thanks for the post. Did you follow this post?
Thank you
Are you referring to the part about updating from an older project? I discovered that it should be fairly straightforward: for Android, you just need to remove the jars that no longer apply, and add those that do apply – they’re all in the (bdsdir)\lib\android\Debug folder. Use the picture at the end of the article as a reference. For iOS, there should be no changes.
Hi Dave,
thanks for this post! I have a strange error. After compiling the project, I get the error message saying that there is no android-device to deploy. Other projects work normally, but your project doesn’t. I tried on 10.1 and 10.2 … same on both.
Can this be the reason because all libraries which end with 7.0.0.dex.jar are not available and marked with an “x” … i tried to get the files somewhere, but with no luck.
btw, I’m on Android 7.1.2
The .jar files are available in Delphi 10.2.3, so if you have 10.2.2 or earlier it would require some “tweaking” to make it work. I don’t think the message you are seeing is related though; it means it thinks you have no device connected.
I found the mistake, I inserted the values in strings.xml at the wrong place
I have the same problem like Fernando and Stanislav. The notification arrives. I can see the correct notification text which I sent via console when the application is closed and I swipe down on the home screen (where all notifications are shown). In this case the app doesn’t write anything to the FCM Messages Memo. But when I send the test Message and the app is open, I get the following entry:
gcm.message_id = 0: 1534728175838413%e149c2bef14978654
gcm.ttl = 6546546
gcm.from = 182139545245
gcm.sent_time = 1534728175799
The message itself doesn’t show up.
I’m on Android 7.1.2 / Xiaomi Note 5A
Any idea?
I think there are two problems.
1.) the app doesn’t wake up when it is in background and a notification arrives.
2.) the message text itself doesn’t show up when the App is in foreground. Instead a message_id, ttl, from and send_time is showing up in the memo
The app isn’t supposed to “wake up” when it is in the background, however the Firebase message service is supposed to present a notification to Android which should show up on the screen. I suggest using Monitor (as per section 10 in the original article) to check the logcat messages to see whether there are any errors or other messages that may indicate what the problem is.
As for when the app is in the foreground, no notification being presented is by design, although I had considered changing it so that it is consistent with the behaviour on iOS. You can fix this by modifying this unit:
https://github.com/DelphiWorlds/KastriFree/blob/master/Features/Firebase/DW.Firebase.Messaging.Android.pas
Namely by removing the if not IsForeground check on line 138, so that the notification is published regardless of whether or not the app is in the foreground
thank you so much for helping me.
The monitor log after compiling, running the app and sending a message outputs the following, but I don’t know if there is something wrong:
09-04 22:47:21.636: D/FirebaseApp(3487): com.google.firebase.auth.FirebaseAuth is not linked. Skipping initialization.
09-04 22:47:21.637: D/FirebaseApp(3487): com.google.firebase.crash.FirebaseCrash is not linked. Skipping initialization.
09-04 22:47:21.638: D/FirebaseApp(3487): com.google.android.gms.measurement.AppMeasurement is not linked. Skipping initialization.
09-04 22:47:21.639: I/FirebaseInitProvider(3487): FirebaseApp initialization successful
09-04 22:47:21.683: D/AccessibilityManager(3487): current package=com.embarcadero.tasker, accessibility manager mIsFinalEnabled=false, mOptimizeEnabled=true, mIsUiAutomationEnabled=false, mIsInterestedPackage=false
09-04 22:47:22.002: W/linker(3487): /data/app/com.embarcadero.tasker-1/lib/arm/libtasker.so: unused DT entry: type 0xf arg 0x1069d
09-04 22:47:22.732: I/Adreno-EGL(3487): : EGL 1.4 QUALCOMM build: AU_LINUX_ANDROID_LA.UM.5.5.R1.07.01.02.269.046_msm8937_64_refs/tags/AU_LINUX_ANDROID_LA.UM.5.5.R1.07.01.02.269.046__release_AU (I09d312ff84)
09-04 22:47:22.732: I/Adreno-EGL(3487): OpenGL ES Shader Compiler Version: XE031.09.00.04
09-04 22:47:22.732: I/Adreno-EGL(3487): Build Date: 07/24/17 Mon
09-04 22:47:22.732: I/Adreno-EGL(3487): Local Branch:
09-04 22:47:22.732: I/Adreno-EGL(3487): Remote Branch: refs/tags/AU_LINUX_ANDROID_LA.UM.5.5.R1.07.01.02.269.046
09-04 22:47:22.732: I/Adreno-EGL(3487): Local Patches: NONE
09-04 22:47:22.732: I/Adreno-EGL(3487): Reconstruct Branch: NOTHING
09-04 22:47:22.741: E/libEGL(3487): call to OpenGL ES API with no current context (logged once per thread)
09-04 22:47:22.741: E/libEGL(3487): call to OpenGL ES API with no current context (logged once per thread)
09-04 22:47:22.741: E/libEGL(3487): validate_display:99 error 3008 (EGL_BAD_DISPLAY)
09-04 22:47:22.741: E/libEGL(3487): call to OpenGL ES API with no current context (logged once per thread)
09-04 22:47:22.743: W/Adreno-ES20(3487): : open failed: errno 13
09-04 22:47:22.739: W/.embarcadero.tasker(3487): type=1400 audit(0.0:4251): avc: denied { read } for name=”gpuclk” dev=”sysfs” ino=21015 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:sysfs:s0 tclass=file permissive=0
09-04 22:47:22.906: I/info(3487): android.permission.ACCESS_COARSE_LOCATION denied
09-04 22:47:22.906: I/info(3487): android.permission.ACCESS_FINE_LOCATION denied
09-04 22:47:22.907: I/info(3487): android.permission.CAMERA denied
09-04 22:47:22.908: I/info(3487): android.permission.READ_EXTERNAL_STORAGE denied
09-04 22:47:22.908: I/info(3487): android.permission.WRITE_EXTERNAL_STORAGE denied
09-04 22:47:22.910: I/Timeline(3487): Timeline: Activity_launch_request time:96094567 intent:Intent { act=android.content.pm.action.REQUEST_PERMISSIONS pkg=com.google.android.packageinstaller (has extras) }
09-04 22:47:23.425: I/info(3487): +TPlatformFirebaseMessaging.HandleMessageReceived
09-04 22:47:23.425: I/info(3487): -TPlatformFirebaseMessaging.HandleMessageReceived
09-04 22:47:24.999: D/FirebaseInstanceId(3487): topic sync succeeded
09-04 22:47:25.008: V/DWFirebaseMessagingService(3487): onCreate
09-04 22:47:25.011: V/DWFirebaseMessagingService(3487): onNewToken
09-04 22:47:25.011: V/DWFirebaseMessagingService(3487): Sending token broadcast
09-04 22:47:25.020: I/info(3487): FCM Token:
09-04 22:47:25.053: I/info(3487): Token in FCMTokenReceivedHandler:
09-04 22:48:12.904: V/BoostFramework(3487): BoostFramework() : mPerf = com.qualcomm.qti.Performance@8332d7d
09-04 22:48:21.277: V/DWFirebaseMessagingService(3487): onCreate
09-04 22:48:21.289: W/FirebaseMessaging(3487): Unable to log event: analytics library is missing
09-04 22:48:21.294: W/FirebaseMessaging(3487): Unable to log event: analytics library is missing
09-04 22:48:21.295: V/DWFirebaseMessagingService(3487): +onMessageReceived
09-04 22:48:21.296: V/DWFirebaseMessagingService(3487): -onMessageReceived
09-04 22:48:21.297: I/info(3487): +TPlatformFirebaseMessaging.HandleMessageReceived
09-04 22:48:21.317: I/info(3487): -TPlatformFirebaseMessaging.HandleMessageReceived
I’ve taken the parts out of your comment that contain your token, just in case 🙂
Was the app in the background when this message was sent? It looks like it was being received, hence the “TPlatformFirebaseMessaging.HandleMessageReceived” entries.
How are the messages being sent? i.e. are you using the Firebase Console, or some other method? What does the payload of the message being *sent* look like, i.e. does it look like this?:
{
“to”: “(your-token-goes-here)”,
“data”: {
“notification_title”: “Firebase Cloud Messaging rules!”,
“notification_largeicon”: “https://avatars3.githubusercontent.com/u/22670829?v=3&s=460”,
“notification_text”: “Congratulations, you received a message”,
“notification_vibrate”: “1”,
“notification_visibility”: “1”,
“notification_priority”: “1”,
“notification_onlyalertonce”: “1”
}
}
I sent the message via “Google Firebase Test Messaging Service” and it was not working this way. Now I tried sending the message manually like you described in section 10… and… what should I say… it works 🙂
B.t.w. the link in section 10 (Hurl website) doesn’t work, so I wrote a small application for posting the data.
But since I have to enter the token in the “to” section of the json data part, do you know if this token changes sometimes? If this token changes regularly, the service would be useless because the “sender application” must be updated over and over?!?
Thanks for the heads up about HURL. It has now moved to Runscope:
https://www.runscope.com/
Which is far less convenient than HURL was. I have a tool of my own that I use for testing that I may make available publicly.
To answer your question about the token: it should not change during the life of the application (it will definitely change on an uninstall/reinstall of the app), however you must be prepared for when it does. To this end, it is wise to keep track of the value (i.e. store it on the device), and notify your back end (i.e. a webserver) where you manage sending of messages from, of the change.
Good idea to keep track of the token and update the server.
You got 2 beer (at least in Austria it would be 2) 🙂
Thanks!! It’ll be about 1.5 beers here 😉
Hi Dave! I’m still looking for a solution for Android 8.0. If the application is in the foreground the notification arrives, but if it is not in the background. This is the log I get from the monitor as shown in section 10 of the first article.
09-05 23: 24: 35,286: E / FirebaseMessaging (4917): Error while setting the notification channel
09-05 23: 24: 35.286: E / FirebaseMessaging (4917): java.lang.NoClassDefFoundError: Failed resolution of: Lcom / google / firebase / messaging / $ string;
09-05 23: 24: 35.286: E / FirebaseMessaging (4917): at com.google.firebase.messaging.zza.zzn (Unknown Source: 195)
09-05 23: 24: 35.286: E / FirebaseMessaging (4917): at com.google.firebase.messaging.zza.zzh (Unknown Source: 310)
09-05 23: 24: 35.286: E / FirebaseMessaging (4917): at com.google.firebase.messaging.FirebaseMessagingService.zzd (Unknown Source: 261)
09-05 23: 24: 35.286: E / FirebaseMessaging (4917): at com.google.firebase.iid.zzg.run (Unknown Source: 26)
09-05 23: 24: 35.286: E / FirebaseMessaging (4917): at java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1162)
09-05 23: 24: 35.286: E / FirebaseMessaging (4917): at java.util.concurrent.ThreadPoolExecutor $ Worker.run (ThreadPoolExecutor.java:636)
09-05 23: 24: 35.286: E / FirebaseMessaging (4917): at com.google.android.gms.common.util.concurrent.zza.run (Unknown Source: 7)
09-05 23: 24: 35,286: E / FirebaseMessaging (4917): at java.lang.Thread.run (Thread.java:764)
09-05 23: 24: 35.286: E / FirebaseMessaging (4917): Caused by: java.lang.ClassNotFoundException: Did not find class “com.google.firebase.messaging.R $ string” on path: DexPathList [[zip file “/data/app/com.embarcadero.keepin-YBJZUDV2_SA155FITuRkHA==/base.apk”],nativeLibraryDirectories=[/data/app/com.embarcadero.keepin-YBJZUDV2_SA155FITuRkHA==/lib/arm, / data / app / com.embarcadero.keepin-YBJZUDV2_SA155FITuRkHA == / base.apk! / lib / armeabi-v7a, / system / lib, / system / vendor / lib]
09-05 23: 24: 35,286: E / FirebaseMessaging (4917): at dalvik.system.BaseDexClassLoader.findClass (BaseDexClassLoader.java:93)
09-05 23: 24: 35.286: E / FirebaseMessaging (4917): at java.lang.ClassLoader.loadClass (ClassLoader.java:379)
09-05 23: 24: 35.286: E / FirebaseMessaging (4917): at java.lang.ClassLoader.loadClass (ClassLoader.java:312)
09-05 23: 24: 35,286: E / FirebaseMessaging (4917): … 8 more
Hi Fernando,
did you manage to find any fix for this problem ?
Hi Dave,
your application works very well.
I would like to know if it is possible to send an upstream message from your client application to a server application. via firebase.
Thank you
It would be possible if I extended to code to implement it. I may look into it sometime in the future however at present I have no plans to
Hello and thank you for your code. I am running Delphi 10.2.3 and a Samsung S8+ v 8.0.0. When I run the FCM Revisited I just get profile=0 in the FCM Messages memo. Can you point me in the right direction?
Are you seeing a token in the memo with the “Your device token” heading?
Also, please check the messages in logcat using Monitor, as per section 10 in this article: http://delphiworlds.com/2017/05/add-firebase-cloud-messaging-mobile-apps-part-1/
It may be that the Firebase Messaging Service is not starting, which means you may have missed a step
Thank you. I must have somehow butchered the demo project. I think by setting the API to 26 in Project Manager. Refreshing the source got me past that point and I am now able to receive. I am however getting the following when I send a message and the app isn’t running: (FYI I also had the Entitlement List “Receive push notifications” checked which I learned thru your posts was wrong)
09-09 18:34:23.429: W/FirebaseMessaging(23574): Missing Default Notification Channel metadata in AndroidManifest. Default value will be used.
09-09 18:34:23.439: E/FirebaseMessaging(23574): Error while setting the notification channel
09-09 18:34:23.439: E/FirebaseMessaging(23574): java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/firebase/messaging/R$string;
09-09 18:34:23.439: E/FirebaseMessaging(23574): at com.google.firebase.messaging.zza.zzn(Unknown Source:195)
09-09 18:34:23.439: E/FirebaseMessaging(23574): at com.google.firebase.messaging.zza.zzh(Unknown Source:310)
09-09 18:34:23.439: E/FirebaseMessaging(23574): at com.google.firebase.messaging.FirebaseMessagingService.zzd(Unknown Source:261)
09-09 18:34:23.439: E/FirebaseMessaging(23574): at com.google.firebase.iid.zzg.run(Unknown Source:26)
09-09 18:34:23.439: E/FirebaseMessaging(23574): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
09-09 18:34:23.439: E/FirebaseMessaging(23574): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
09-09 18:34:23.439: E/FirebaseMessaging(23574): at com.google.android.gms.common.util.concurrent.zza.run(Unknown Source:7)
09-09 18:34:23.439: E/FirebaseMessaging(23574): at java.lang.Thread.run(Thread.java:764)
09-09 18:34:23.439: E/FirebaseMessaging(23574): Caused by: java.lang.ClassNotFoundException: Didn’t find class “com.google.firebase.messaging.R$string” on path: DexPathList[[zip file “/data/app/com.embarcadero.FireBaseCloudMessaging-LLza5z6GnSyMvpwPYMHfEw==/base.apk”],nativeLibraryDirectories=[/data/app/com.embarcadero.FireBaseCloudMessaging-LLza5z6GnSyMvpwPYMHfEw==/lib/arm, /data/app/com.embarcadero.FireBaseCloudMessaging-LLza5z6GnSyMvpwPYMHfEw==/base.apk!/lib/armeabi-v7a, /system/lib, /system/vendor/lib]]
09-09 18:34:23.439: E/FirebaseMessaging(23574): at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:93)
09-09 18:34:23.439: E/FirebaseMessaging(23574): at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
09-09 18:34:23.439: E/FirebaseMessaging(23574): at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
09-09 18:34:23.439: E/FirebaseMessaging(23574): … 8 more
09-09 18:34:23.443: D/Notification(23574): allPendingIntents
Fernando (in the comments) is having the same problem. He also has a device with Android 8.0, so perhaps that has something to do with it.
Otherwise, can you check the Libraries node under the Android platform in Project Manager to ensure that it looks like the last image in this article?
Also, perhaps delete the Android folder where the compiler outputs to, and do a Clean and Build.
Thank you! My Libraries look identical to the image in the above post. I have done a clean build and deleted the aforementioned folder. The result…Same outcome.
I also wanted to ask what’s the earliest version of Delphi the Kastri Library will work with?
I’m assuming for the moment that it’s an Android 8.0 specific issue, however: are you using the demo project, or one of your own? If the former, are you able to build an .apk and put it somewhere that I can download/test it from?
Kastri Free may work with Delphi 10.1 Berlin, though it has been a while since I’ve tested it, so no guarantees. It may even work with Delphi 10 Seattle, however I expect for not any versions before that
Dave! Your tool worked like a charm. Thank you! I am able to receive the incoming Push Notifications when the app is opened as well as closed on my Samsung S8+ on Android 8.0.0. (For the benefit of others SENT FROM FIREBASE SEND TOOL THIS IS NOT FUNCTIONAL).
Hi Mike, i am facing the same problem currently. Can i know how you resolved it?
Hi Dave,
I’m trying to get the FCM Revisited demo working but having difficulty with it. I’m using iOS (11.4.1). I’ve set up everything correctly as far as I can tell. I’m using one of my existing App bundle ID’s which I have set up for push notifications. The issue I have is that notifications are not being displayed either when the app is running, in the background or closed. However, when the app is open, I do see that the payload is received in the memo on the screen.
I am sending the payload through the FireBase remote message testing feature from the Firebase Console. I’ve also tested with PostMan which gives the same result.
I did notice that the app doesn’t request notification permission from the user (as iOS requires) so I assume this would prevent any notifications being displayed. To try and fix this, I added a TNotificationCenter component to the form so that the “Request Push Notifications” prompt displays when it is first run (and the notification settings are displayed in the app settings).
However, even when selecting “Allow” for push notifications, I’m still not receiving any visual notification on the screen (except for the JSON in the memo when the app is running).
The communication from server (firebase console) to device is clearly working correctly as the JSON is being delivered, but it doesn’t seem to be triggering the notification on the device itself.
Do you have any ideas as to what may be the issue here? I understand in the tutorial you test on 10.2.3 although I’m using 10.2.2. (I couldn’t see anything in the change log which would affect the push notifications)
Do you have any ideas as to what may be preventing this from working?
Thanks for a great blog!
Hi Graham,
Thanks for stopping by!
“I am sending the payload through the FireBase remote message testing feature from the Firebase Console”
I probably should have had a reminder in the article, that sending messages using the Firebase Console will not be received as “proper” notifications on iOS. Not sure about PostMan, however if the messages can be sent with a payload as per the format at the end of this article:
http://delphiworlds.com/2017/05/adding-firebase-cloud-messaging-mobile-apps-part-2/
They should work. Otherwise, I’m in the process of preparing for release a tool that I use for sending messages.. stay tuned!
Thanks Dave, I’ll give this a go.
Any ideas about the “Permission Request” not showing to allow push notifications? This prompt shows immediately on startup of your “local notifications” demo, but it doesn’t show on the “FCM Revisited” demo. Any ideas? I assume the user would need to see this and select “Allow” before any notifications would show.
Thanks again!
Ok, I may have found a cause of the problem I’m having here. I found a previous DW.iOSapi.Helpers.pas in a different folder on my search path. Will test again and let you know how it goes.
Hello. While you are waiting for Dave to respond, you may want to try the advanced option when sending from the FCM console. In my travels, I read that unless you drop down the Advanced Options and Add some Custom Data, your message isn’t sent properly or rather the way you need it sent. I have not verified this yet.
Thanks Mike, tried this but no change. Going to test with hUrl as Dave suggests. Thanks again!
HI, I’ve had the same kind of problem (on iOS no notification when app was inactive/background but worked when app was active). Using the iOS-console on my OSX (suggested in the prev article) I’ve discovered a message which pointed out that something with the provision-profile was wrong (no valid aps environment entitlement string at app-startup) because I was using a development profile with a wildcard-appID. So check out the (development) provision profile (regenerate and download,install).
Using Delphi 10.2.3 (or apply all 10.2.2 patches).
My apologies! Dave already responded. Just offering something in case you were idle.
Hi Dave,
The demo project is working for me, but when I try to integrate the solution in my own app I get an error on runtime (iOS x64).
The error is ‘ObjectiveC class FIRMessaging not found’. Do you have any hint how to solve this? The Firebase framework-directories are in the project browse-path.
Thanks in advance!
You may be missing the -ObjC linker option as per section 2, here: http://delphiworlds.com/2017/05/adding-firebase-cloud-messaging-mobile-apps-part-2/
Thanks a lot Dave, this solved it!
Hey Dave… Just curious… Should this work in the OSX Xcode iOS Simulator or do I need to be publishing to an actual device as there is no -ObjC option for the simulator?
No, it won’t work on iOS Simulator, since push notifications are not possible on Simulator
Hey Dave! Since I got the Demo app to receive FCM Push messages, I’ve tried to add the functionality to a stub of my application (a skeleton version of my GUI with no significant code). As soon as the app loads on Android it goes out of memory. Not output to Android device monitor as it terminates so quickly. I am thinking I may be missing some deployment necessities.
Your sample app seems to include a ton of items and I am unsure what I need to manually deploy. I am including the customized strings.xml created from the Google JSON file and in the IDE, under Project Manager>Android>Libraries I have made all inclusions and omissions to clone that of your project.
(Not exactly sure how to deploy whole folders in Deployment manager or if that’s necessary)
Can you push me in the right direction?
Kindly,
Mike
Dave I was able to obtain a trace after a reboot of the PC:
41.691: D/InputTransport(10822): Input channel constructed: fd=59
09-13 11:04:41.691: D/ViewRootImpl@a8cc7cb[FMXNativeActivity](10822): setView = DecorView@4d31ba8[FMXNativeActivity] touchMode=true
09-13 11:04:41.693: D/ViewRootImpl@a8cc7cb[FMXNativeActivity](10822): dispatchAttachedToWindow
09-13 11:04:41.713: D/ViewRootImpl@a8cc7cb[FMXNativeActivity](10822): Relayout returned: oldFrame=[0,0][0,0] newFrame=[0,0][1440,2560] result=0x27 surface={isValid=true -894803968} surfaceGenerationChanged=true
09-13 11:04:41.736: D/libEGL(10822): loaded /vendor/lib/egl/libGLES_mali.so
09-13 11:04:41.755: E/libEGL(10822): call to OpenGL ES API with no current context (logged once per thread)
09-13 11:04:41.755: E/libEGL(10822): call to OpenGL ES API with no current context (logged once per thread)
09-13 11:04:41.755: E/libEGL(10822): validate_display:99 error 3008 (EGL_BAD_DISPLAY)
09-13 11:04:41.755: E/libEGL(10822): call to OpenGL ES API with no current context (logged once per thread)
09-13 11:04:41.759: D/mali_winsys(10822): EGLint new_window_surface(egl_winsys_display*, void*, EGLSurface, EGLConfig, egl_winsys_surface**, egl_color_buffer_format*, EGLBoolean) returns 0x3000, [1×1]-format:1
09-13 11:04:42.006: I/info(10822): android.permission.ACCESS_COARSE_LOCATION granted
09-13 11:04:42.006: I/info(10822): android.permission.ACCESS_FINE_LOCATION granted
09-13 11:04:42.006: I/info(10822): android.permission.CAMERA granted
09-13 11:04:42.007: I/info(10822): android.permission.READ_EXTERNAL_STORAGE granted
09-13 11:04:42.007: I/info(10822): android.permission.WRITE_EXTERNAL_STORAGE granted
09-13 11:04:42.009: W/System.err(10822): java.lang.IllegalStateException: Default FirebaseApp is not initialized in this process com.edgevcorp.ClubIOMobile. Make sure to call FirebaseApp.initializeApp(Context) first.
09-13 11:04:42.016: W/System.err(10822): at com.google.firebase.FirebaseApp.getInstance(SourceFile:218)
09-13 11:04:42.016: W/System.err(10822): at com.google.firebase.iid.FirebaseInstanceId.getInstance(Unknown Source)
09-13 11:04:42.016: W/System.err(10822): at com.delphiworlds.kastri.DWFirebaseMessagingService.queryToken(DWFirebaseMessagingService.java:49)
09-13 11:04:42.016: W/System.err(10822): at android.app.NativeActivity.onSurfaceCreatedNative(Native Method)
09-13 11:04:42.016: W/System.err(10822): at android.app.NativeActivity.surfaceCreated(NativeActivity.java:267)
09-13 11:04:42.016: W/System.err(10822): at com.embarcadero.firemonkey.FMXNativeActivity.surfaceCreated(FMXNativeActivity.java:410)
09-13 11:04:42.016: W/System.err(10822): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2256)
09-13 11:04:42.016: W/System.err(10822): at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1522)
09-13 11:04:42.016: W/System.err(10822): at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7098)
09-13 11:04:42.016: W/System.err(10822): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:927)
09-13 11:04:42.016: W/System.err(10822): at android.view.Choreographer.doCallbacks(Choreographer.java:702)
09-13 11:04:42.016: W/System.err(10822): at android.view.Choreographer.doFrame(Choreographer.java:638)
09-13 11:04:42.016: W/System.err(10822): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:913)
09-13 11:04:42.016: W/System.err(10822): at android.os.Handler.handleCallback(Handler.java:751)
09-13 11:04:42.016: W/System.err(10822): at android.os.Handler.dispatchMessage(Handler.java:95)
09-13 11:04:42.016: W/System.err(10822): at android.os.Looper.loop(Looper.java:154)
09-13 11:04:42.016: W/System.err(10822): at android.app.ActivityThread.main(ActivityThread.java:6682)
09-13 11:04:42.016: W/System.err(10822): at java.lang.reflect.Method.invoke(Native Method)
09-13 11:04:42.016: W/System.err(10822): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
09-13 11:04:42.016: W/System.err(10822): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)
Hi Mike. You’ll want to revisit steps 7 and 8 from the old FCM demo, part 1:
http://delphiworlds.com/2017/05/add-firebase-cloud-messaging-mobile-apps-part-1/
For step 7 use your strings.xml file and the /res folder located in ThirdParty/PlayServices/Android from the KastriFree project.
As for step 8 seems like you need to include in your AndroidManifest.template.xml file some chunks from the same file in the FCM Revisited demo project that are not enclosed inside **** FCM **** comments. Check carefully and you will find them.
Thank you! I’ll bang at it.
Hi Dave,
a big thank you for your work.
it works great with android.
but when I build the project with the iOS64 platform and have followed all the steps I get this error:
[DCC Erreur] E2597 Undefined symbols for architecture arm64:
Error: “_OBJC_METACLASS_$_NSObject”, referenced from: _OBJC_METACLASS_$_GPBWrappersRoot in D:\Dev\ThirdParty\Firebase\iOS\Firebase.5.5.0\Messaging\Protobuf.framework\Protobuf(Wrappers.pbobjc.o); _OBJC_METACLASS_$_GPBDoubleValue in D:\Dev\ThirdParty\Firebase\iOS\Firebase.5.5.0\Messaging\Protobuf.framework\Protobuf(Wrappers.pbobjc.o); _OBJC_METACLASS_$_GPBFloatValue in D:\Dev\ThirdParty\Firebase\iOS\Firebase.5.5.0\Messaging\Protobuf.framework\Protobuf(Wrappers.pbobjc.o); _OBJC_METACLASS_$_GPBInt64Value in D:\Dev\ThirdParty\Firebase\iOS\Firebase.5.5.0\Messaging\Protobuf.framework\Protobuf(Wrappers.pbobjc.o); _OBJC_METACLASS_$_GPBUInt64Value in D:\Dev\ThirdParty\Firebase\iOS\Firebase.5.5.0\Messaging\Protobuf.framework\Protobuf(Wrappers.pbobjc.o); _OBJC_METACLASS_$_GPBInt32Value in D:\Dev\ThirdParty\Firebase\iOS\Firebase.5.5.0\Messaging\Protobuf.framework\Protobuf(Wrappers.pbobjc.o); _OBJC_METACLASS_$_GPBUInt32Value in D:\Dev\ThirdParty\Firebase\iOS\Firebase.5.5.0\Messaging\Protobuf.framework\Protobuf(Wrappers.pbobjc.o); …
Error: “_OBJC_CLASS_$_NSObject”, referenced from: _OBJC_CLASS_$_GPBUInt32UInt32Dictionary in D:\Dev\ThirdParty\Firebase\iOS\Firebase.5.5.0\Messaging\Protobuf.framework\Protobuf(GPBDictionary.o); _OBJC_CLASS_$_GPBUInt32Int32Dictionary in D:\Dev\ThirdParty\Firebase\iOS\Firebase.5.5.0\Messaging\Protobuf.framework\Protobuf(GPBDictionary.o); _OBJC_CLASS_$_GPBUInt32UInt64Dictionary in D:\Dev\ThirdParty\Firebase\iOS\Firebase.5.5.0\Messaging\Protobuf.framework\Protobuf(GPBDictionary.o); _OBJC_CLASS_$_GPBUInt32Int64Dictionary in D:\Dev\ThirdParty\Firebase\iOS\Firebase.5.5.0\Messaging\Protobuf.framework\Protobuf(GPBDictionary.o); _OBJC_CLASS_$_GPBUInt32BoolDictionary in D:\Dev\ThirdParty\Firebase\iOS\Firebase.5.5.0\Messaging\Protobuf.framework\Protobuf(GPBDictionary.o); _OBJC_CLASS_$_GPBUInt32FloatDictionary in D:\Dev\ThirdParty\Firebase\iOS\Firebase.5.5.0\Messaging\Protobuf.framework\Protobuf(GPBDictionary.o); _OBJC_CLASS_$_GPBUInt32DoubleDictionary in D:\Dev\ThirdParty\Firebase\iOS\Firebase.5.5.0\Messaging\Protobuf.framework\Protobuf(GPBDictionary.o);
…
D:\Dev\ThirdParty\Firebase\iOS\Firebase.5.5.0\Analytics\FirebaseCore.framework\FirebaseCore(FIRApp.o);
ld: symbol(s) not found for architecture arm64
I need help please.
I have the same problem compiling against any iOS SDK that is greater than 11.2. This is a known issue:
https://quality.embarcadero.com/browse/RSP-20728
Try compiling against iOS 11.2 SDK
Hi Dave,
Thank you very much for sharing this excellent work. It’s helped me a lot.
I have an app with several forms. I can receive push messages without any problem when the main form is active but I don’t receive push message when another form is displayed
Could you help me?
What could I do to receive messages even if the user is in another (not main) form?
Thanks in advance.
Hi Juan,
Without seeing the code, I really couldn’t say what the problem is
Dear Dave,
Is there any way to send silent notification, aka data only, without showing the notification to android? Since in the past, data is the only section, no notification will be displayed.
For the time being, if I send a Data Message, there will be an empty notification shown in the system tray.
Firebase Cloud Messages has two types of messages:
Notification Message: this type of message has the same behavior as the GCM messages
FCM automatically displays the message to end-user devices on behalf of the client app. Notification messages have a predefined set of user-visible keys
Data Message: this type has the behavior you described above.
Client app is responsible for processing data messages.
Data messages have only custom key-value pairs.
Hi Alex,
As per Robbert’s question, it would require a change to the Java code that resides in dw-firebase.jar. I may look at supporting this later.
Hi again Alex,
For silent push notifications on Android, the solution may be a bit more challenging because a notification may be received when the app is not running.
The only way to execute Delphi code in that scenario is to have the messaging service descendant (which is in the Java code) either launch the Delphi application, or start a service that you’ve done in Delphi code, that is associated with your application. Obviously if your app starts it’s not very “silent”, so it would need to be a service.
This presents a new problem: for the service types that are supported (and actually work) in Delphi, the service would need to be started in the foreground (due to background execution restrictions on API 26 or greater), which requires a notification that the user will see, so once again, not “silent”. It might be possible to use an IntentService, however presently these do not work properly in the current version of Delphi.
So presently, the only way to process a notification as “silent” (at least on API 26+) is to write your own Java code that handles the notification, at least until the issue with IntentService is fixed:
https://quality.embarcadero.com/browse/RSP-18015
On iOS “silent” notifications are easier to handle, however on later versions of iOS, the notification is not guaranteed to be received by your code:
https://stackoverflow.com/questions/44796613/silent-pushes-not-delivered-to-the-app-on-ios-11
(there’s information in the comments of some of the answers)
Thanks Dave. Your code is great.
Hi Dave, your work has helped the community a lot, I am very grateful for your posts, would you know if these problems were solved in 10.4?
I would like to send a silent notification to the device so that it can perform certain tasks, with the app in the foreground and background I can receive and handle these notifications, but with the closed app not.
If silent notifications don’t work, would it be possible with push notifications visible to execute code even with the app closed? Even for a few seconds.
In the google documentation it is reported that upon receiving the notification even with the app closed, a communication window of a few seconds is opened.
Thanks in advance, Dave.
> would it be possible with push notifications visible to execute code even with the app closed?
This is supposed to be possible, however I’ve experienced issues with making this work – iOS is very strict about what code can execute in the background, especially when the app is not running.
> In the google documentation it is reported that upon receiving the notification even with the app closed, a communication window of a few seconds is opened.
Can you give a link to where this is claimed?
my first reply didn’t publish
Follow the link:
https://firebase.google.com/docs/cloud-messaging/android/receive#handling_messages
https://firebase.google.com/docs/cloud-messaging/concept-options#notifications_and_data_messages
For testing I’m using Data Messages
High Priority Type
to force the device to wake up in an eventual “snooze” mode
Other Link:
https://android-developers.googleblog.com/2018/09/notifying-your-users-with-fcm.html
“Android 9 Pie will also impose background execution limits when battery saver is on. Starting a background service will lead to IllegalStateException from a normal priority FCM message. High priority messages do grant you a short whitelist window that allows you to start a background service. However, starting a background service with a network call will put the service at risk of getting terminated by the system, because the short execution window is only intended to be used for posting a notification.”
thank you in advance, Dave.
Great article!
I like to create two android channels for my app (“NewsItem” and “MatchResult”). How do I create channels in my app with your solution?
Hi Robbert,
The code as it stands supports only one channel, however I may look at updating it in the future to support more than one. It would require changes to the Java code in this file:
https://github.com/DelphiWorlds/KastriFree/blob/master/Java/DWNotificationPublisher.java
..which would then require a rebuild of the dw-firebase.jar file. I am planning on publishing an article about how to change the Java sources and rebuild the jars, however due to other commitments it may be another month or so away.
Hey Dave,
great work and nice explanation to get easily Firebase-Notification implemented in our project.
Actually we face the problem that on older Android versions / Devices we get the error that the default FirebaseApp is not initialized.
10-30 10:55:57.635: I/FirebaseInitProvider(9554): FirebaseApp initialization unsuccessful
10-30 10:56:05.415: W/System.err(9554): java.lang.IllegalStateException: Default FirebaseApp is not initialized in this process xxxx. Make sure to call FirebaseApp.initializeApp(Context) first.
On newer devices there is no problem and it works like a charm…
So i don’t think that there is a general mistake in our project (putting strings.xml wrong or something).
Or i couldn’t found it out yet.
I think that this issue is well known but i didn’t get it how to transfer this to Delphi.
And if this resolves the problem because FirebaseInitProvider should initialize Default FirebaseApp and it does but is not succesfully – is there some more details what cause this?
https://stackoverflow.com/questions/40081539/default-firebaseapp-is-not-initialized
Hi Andy,
What versions of Android are on the devices you are using it on? Can you try the following?:
To the implementation uses clause of DW.Firebase.Messaging.Android, add:
DW.FirebaseApp.Android
To the TPlatformFirebaseMessaging.Create method, add the following just after the call to inherited:
TPlatformFirebaseApp.Start;
Hi,
The FCMREvisited demo worked fine!
But when I implement TFirebaseMessaging in my own project and run on a Android 8.0 device, I also get W/System.err(28157): java.lang.IllegalStateException: Default FirebaseApp is not initialized in this process com.rjm.myapp. Make sure to call FirebaseApp.initializeApp(Context) first.
I’ve made the two changes in DW.Firebase.Messaging.Android as you suggested and this indeed solved the problem!!! I receive the device token in my app now.
Thanks!
BTW Not sure why the demo did not have this issue. Will you commit this fix of DW.Firebase.Messaging.Android in the KastriFreeLib?
I’m wondering, in the FCMRevisited demo project, why is first asked for location, camera and external storage permission? Why is this needed for notifications? Can I just only ask for permission for notifications (FFCM.RequestAuthorization)?
Hi Robbert,
I’m actually not sure why I added requesting those permissions in the app! I expect I had a good reason; perhaps it was to demonstrate requesting permissions because this revisited demo is targeting API 26+?
I’ll update the article and code to indicate that the permissions are not actually required for notifications; thanks!
Hi Dave, I am currently facing problem with Push Notification on Android O.
I am having exactly same error like Fernando and Mike.
Tested on Android 8.1, Android 8.0, using sdk 26.1.1 32bit, rad studio 10.2
Here is the log from Monitor:
10-31 11:44:54.720: E/FirebaseMessaging(12259): Error while setting the notification channel
10-31 11:44:54.720: E/FirebaseMessaging(12259): java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/firebase/messaging/R$string;
10-31 11:44:54.720: E/FirebaseMessaging(12259): at com.google.firebase.messaging.zza.zzn(Unknown Source:195)
10-31 11:44:54.720: E/FirebaseMessaging(12259): at com.google.firebase.messaging.zza.zzh(Unknown Source:310)
10-31 11:44:54.720: E/FirebaseMessaging(12259): at com.google.firebase.messaging.FirebaseMessagingService.zzd(Unknown Source:261)
10-31 11:44:54.720: E/FirebaseMessaging(12259): at com.google.firebase.iid.zzg.run(Unknown Source:26)
10-31 11:44:54.720: E/FirebaseMessaging(12259): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
10-31 11:44:54.720: E/FirebaseMessaging(12259): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
10-31 11:44:54.720: E/FirebaseMessaging(12259): at com.google.android.gms.common.util.concurrent.zza.run(Unknown Source:7)
10-31 11:44:54.720: E/FirebaseMessaging(12259): at java.lang.Thread.run(Thread.java:784)
10-31 11:44:54.720: E/FirebaseMessaging(12259): Caused by: java.lang.ClassNotFoundException: Didn’t find class “com.google.firebase.messaging.R$string” on path: DexPathList[[zip file “/data/app/com.embarcadero.PushNotification-FCANmIQ2fJpOTyq7kMEYxg==/base.apk”],nativeLibraryDirectories=[/data/app/com.embarcadero.PushNotification-FCANmIQ2fJpOTyq7kMEYxg==/lib/arm, /data/app/com.embarcadero.PushNotification-FCANmIQ2fJpOTyq7kMEYxg==/base.apk!/lib/armeabi-v7a, /system/lib, /vendor/lib, /product/lib]]
10-31 11:44:54.720: E/FirebaseMessaging(12259): at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:125)
10-31 11:44:54.720: E/FirebaseMessaging(12259): at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
10-31 11:44:54.720: E/FirebaseMessaging(12259): at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
10-31 11:44:54.720: E/FirebaseMessaging(12259): … 8 more
To further clarify, I just cloned the whole repo, added the strings.xml then run the demo.
The message was sent using own server application.
What happens when you uncomment this line:
from AndroidManifest.template.xml? I think it was commented out because it was apparently not needed.
Hi Dave, thank you for replying.
The problem still persists with same error no matter that line is commented or not.
Will this problem related to sdk version?
Maybe a litte bit off topic, but while I was configuring my android manifest for FCM, I encountered two mysteries I do not understand:
– In the manifest template of FCMRevisited demo android:debuggable=”%debuggable%” will be generated as android:debuggable=”true” (which is needed to see the package name in Android Device Monitor). In my own app however it is generated as android:debuggable=”false”. Which project option is responsible for this value?
– In my own app the build process adds to the generated manifest (it is not in the template). Which project setting is responsible for this. I guess with the KastriFree solution for FCM this receiver is not needed anymore.
I carefully compared all project options of the FCMRevisited demo with those of my own project, but I can not find any differences.
Any ideas?
Thanks, Robbert
For the second point, I meant:
receiver android:name=”com.embarcadero.rtl.notifications.NotificationAlarm” />
is added. Which project setting is responsible for this?
I have no idea which setting changes %debuggable%. I had thought it might be in the Version Info, but it does not seem to be there. I’ll have a deeper look when I have time, however perhaps this may give a clue:
https://stackoverflow.com/a/29130191/3164070
For the notification receiver, it’s the Receive push notifications option in the Entitlement List. Do not check this option if you’re using my FCM solution.
Hi Dave,
I’m now trying to run my project for iOS. I added and reloaded all additional frameworks, but when I then build my project, I get:
DW.iOSapi.Firebase.pas(164): F2051 Unit iOSapi.StoreKit was compiled with a different version of iOSapi.UIKit.UIViewController
Any suggestion?
Robbert
It means the compiler is finding the source for the iOSapi.StoreKit unit, and is attempting to compile DW.iOSapi.Firebase for it, but does not find a matching iOSapi.UIKit.
i.e. You have the source for iOSapi.StoreKit unit somewhere in the compiler path but not the source for iOSapi.UIKit (i.e. the compiler finds a compiled .DCU instead).
Check the IDE library paths (i.e. in Tools|Options, Environment Options\Delphi Options\Library, Library Path value), and the project paths (i.e. Project Options, Delphi Compiler, Search path value)
Thanks for your response. It appeared to be caused by Alcinoe library (which I use for double buffered controls). But this was solved after putting iOSapi.StoreKit.pas, System.iOS.Sensors.pas (with an added implementation for DidVisit) and iOSapi.CoreMotion.pas in the project’s search path.
After that it appeared also to be needed to add framework IOSurface (I’ve somehow missed it), and to put the 10 Firebase.5.5.0 frameworks in the search path (maybe group them in one directory?).
Now I was able to build my app for iOS (SDK 11.2) and deploy it.
Unfortunately my app carashes on start up (even before GRIJJY error reporting can save the stack)
Below the iOS crash report, I can not make much of it.
Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
Triggered by Thread: 0
Application Specific Information:
abort() called
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 libsystem_kernel.dylib 0x00000001f29b0104 0x1f298d000 + 143620
1 libsystem_pthread.dylib 0x00000001f2a2b0e0 0x1f2a29000 + 8416
2 libsystem_c.dylib 0x00000001f2907d78 0x1f28b0000 + 359800
3 libc++abi.dylib 0x00000001f1fcff78 0x1f1fce000 + 8056
4 libc++abi.dylib 0x00000001f1fd007c 0x1f1fce000 + 8316
5 libc++abi.dylib 0x00000001f1fdc0fc 0x1f1fce000 + 57596
6 libc++abi.dylib 0x00000001f1fdc180 0x1f1fce000 + 57728
7 libdispatch.dylib 0x00000001f2853498 0x1f27f2000 + 398488
8 libdispatch.dylib 0x00000001f27f6e58 0x1f27f2000 + 20056
9 FrontBoardServices 0x00000001f5889640 0x1f583e000 + 308800
10 FrontBoardServices 0x00000001f58892cc 0x1f583e000 + 307916
11 FrontBoardServices 0x00000001f58898e8 0x1f583e000 + 309480
12 CoreFoundation 0x00000001f2da95b8 0x1f2cfd000 + 705976
13 CoreFoundation 0x00000001f2da9538 0x1f2cfd000 + 705848
14 CoreFoundation 0x00000001f2da8e1c 0x1f2cfd000 + 704028
15 CoreFoundation 0x00000001f2da3ce8 0x1f2cfd000 + 683240
16 CoreFoundation 0x00000001f2da35b8 0x1f2cfd000 + 681400
17 GraphicsServices 0x00000001f5017584 0x1f500c000 + 46468
18 UIKitCore 0x000000021f57cbc8 0x21ec99000 + 9321416
19 CompetitionApp 0x00000001016272a0 0x101074000 + 5976736
20 CompetitionApp 0x0000000101729b0c 0x101074000 + 7035660
21 CompetitionApp 0x0000000101ce7bec 0x101074000 + 13057004
22 libdyld.dylib 0x00000001f2863b94 0x1f2863000 + 2964
Hi Robbert,
It might help to use the Console app (on the Mac in Applications/Utilities) to see what messages (especially errors) related to the app show up in there.
Hi, unfortunately I don’t own a MAC. I use MacinCloud to deploy my ipa and to deliver it to iTunes Connect. I then test my app on my iPad using TestFlight. All I have is the crash report of my iPad which I partly included in my last post.
That’s going to make it extremely difficult to determine the problem
Yes, I’m afraid so. I will dive deeper in it when I have more time.
But for now, for iOS, I wil stick with System.PushNotification.TPushServiceConnection/FMX.PushNotification.iOS; it still works fine for me.
For Android I used to use System.PushNotification.TPushServiceConnection/FMX.PushNotification.Android, but that appeared to be broken for targetSDK 26. However your KastriFree solution for Android proofed to be a perfect replacement!
Hi, I tried to run the NotificationsDemo (for local notifications), but during the build I get:
[Exec Error] de opdracht PATH … & “C:\Users\Public\Documents\Embarcadero\Studio\19.0\CatalogRepository\AndroidSDK-2433_19.0.29899.2631\build-tools\22.0.1\dx.bat” –dex –output=”C:\Users\UserXXX\Projecten\KastriFreeLib\Demos\Notifications\Android\Debug\dw-multireceiver-dexed.jar” “C:\Users\UserXXX\Projecten\KastriFreeLib\Lib\dw-multireceiver.jar” is afgesloten met code 1.
(I replaced the path with …, because it is very long, and the error is partly in Dutch but its saying something like: “the command PATH …… has been closed with code 1”.
Any idea? It probably has to do something with dw-multireceiver.jar, because when I add this library to my main project, I get the same error.
That problem is usually related to your Android SDK configuration. Won’t know for sure without the detail from the Output tab of the Messages window
Sorry, did not know to find more details on the Output tab. But here it is (btw I use Android SDK 24.3.3 32 bit):
Build started 8-11-2018 13:17:27.
__________________________________________________
Project “C:\Users\UserXXX\Projecten\KastriFreeLib\Demos\Notifications\NotificationsDemo.dproj” (Build target(s)):
Target BuildPredexedJar:
PATH C:\Program Files\Java\jdk1.8.0_66\bin;C:\Users\Public\Documents\Embarcadero\InterBase\redist\InterBase2017\IDE_spoof;C:\Users\Public\Documents\Embarcadero\InterBase\redist\InterBase2017\IDE_spoof;C:\Program Files (x86)\Embarcadero\Studio\19.0\bin;C:\Users\Public\Documents\Embarcadero\Studio\19.0\Bpl;C:\Program Files (x86)\Embarcadero\Studio\19.0\bin64;C:\Users\Public\Documents\Embarcadero\Studio\19.0\Bpl\Win64;C:\ProgramData\Oracle\Java\javapath;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Windows Live\Shared;C:\Program Files (x86)\Windows Kits\10\Windows Performance Toolkit\;C:\Program Files\jEdit;C:\WINDOWS\System32\OpenSSH\;C:\Users\Public\Documents\Embarcadero\Studio\16.0\Bpl;%USERPROFILE%\AppData\Local\Microsoft\WindowsApps;;C:\Users\UserXXX\Projecten\AlcinoeLib\lib\bpl\alcinoe\Win32\tokyo;C:\Users\Public\Documents\Embarcadero\Studio\19.0\Bpl & “C:\Users\Public\Documents\Embarcadero\Studio\19.0\CatalogRepository\AndroidSDK-2433_19.0.29899.2631\build-tools\22.0.1\dx.bat” –dex –output=”C:\Users\UserXXX\Projecten\KastriFreeLib\Demos\Notifications\Android\Debug\dw-multireceiver-dexed.jar” “C:\Users\UserXXX\Projecten\KastriFreeLib\Lib\dw-multireceiver.jar”
UNEXPECTED TOP-LEVEL EXCEPTION:
com.android.dx.cf.iface.ParseException: bad class file magic (cafebabe) or version (0034.0000)
at com.android.dx.cf.direct.DirectClassFile.parse0(DirectClassFile.java:472)
at com.android.dx.cf.direct.DirectClassFile.parse(DirectClassFile.java:406)
at com.android.dx.cf.direct.DirectClassFile.parseToInterfacesIfNecessary(DirectClassFile.java:388)
at com.android.dx.cf.direct.DirectClassFile.getMagic(DirectClassFile.java:251)
at com.android.dx.command.dexer.Main.processClass(Main.java:704)
at com.android.dx.command.dexer.Main.processFileBytes(Main.java:673)
at com.android.dx.command.dexer.Main.access$300(Main.java:83)
at com.android.dx.command.dexer.Main$1.processFileBytes(Main.java:602)
at com.android.dx.cf.direct.ClassPathOpener.processArchive(ClassPathOpener.java:284)
at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:166)
at com.android.dx.cf.direct.ClassPathOpener.process(ClassPathOpener.java:144)
at com.android.dx.command.dexer.Main.processOne(Main.java:632)
at com.android.dx.command.dexer.Main.processAllFiles(Main.java:510)
at com.android.dx.command.dexer.Main.runMonoDex(Main.java:280)
at com.android.dx.command.dexer.Main.run(Main.java:246)
at com.android.dx.command.dexer.Main.main(Main.java:215)
at com.android.dx.command.Main.main(Main.java:106)
…while parsing com/delphiworlds/kastri/DWMultiBroadcastReceiver.class
1 error; aborting
Hello Dave, congratulations on your work.
I’m trying to run the Demo and when it runs it returns the error:
‘java.lang.IllegalStateException: Default FirebaseApp is not initialized in this process com.embarcadero.delphiteste. Make sure to call FirebaseApp.initializeApp (Context) first. ‘
What’s wrong?
“com.embarcadero.delphiteste” is the name of my app.
Hi Danny,
Can you update your copy of this file:
https://github.com/DelphiWorlds/KastriFree/blob/master/Features/Firebase/DW.Firebase.Messaging.Android.pas
..and see what happens? Someone else had a similar issue, and I noticed this change had not been checked in.
Dave compiled, but did not display the token in the app.
But it doesn’t error now? Check the messages in logcat using Monitor, as per section 10 in this article: http://delphiworlds.com/2017/05/add-firebase-cloud-messaging-mobile-apps-part-1/
Log:
11-09 20:54:10.354: W/ResourcesManager(8935): getTopLevelResources: /data/app/com.embarcadero.delphiteste-2/base.apk / 1.0 running in com.embarcadero.delphiteste rsrc of package com.embarcadero.delphiteste
11-09 20:54:10.364: I/InjectionManager(8935): Inside getClassLibPath + mLibMap{0=, 1=}
11-09 20:54:10.375: D/ResourcesManager(8935): For user 0 new overlays fetched Null
11-09 20:54:10.405: I/InjectionManager(8935): Inside getClassLibPath caller
11-09 20:54:10.525: D/FirebaseApp(8935): com.google.firebase.auth.FirebaseAuth is not linked. Skipping initialization.
11-09 20:54:10.525: D/FirebaseApp(8935): com.google.firebase.crash.FirebaseCrash is not linked. Skipping initialization.
11-09 20:54:10.525: D/FirebaseApp(8935): com.google.android.gms.measurement.AppMeasurement is not linked. Skipping initialization.
11-09 20:54:10.525: I/FirebaseInitProvider(8935): FirebaseApp initialization successful
(snip)
11-09 20:54:17.381: I/info(8935): +TPlatformFirebaseMessaging.HandleMessageReceived
11-09 20:54:17.411: I/info(8935): -TPlatformFirebaseMessaging.HandleMessageReceived
11-09 20:54:17.531: D/ViewSystem(8935): ViewRootImpl >> surfaceChanged W=720, H=1280)
11-09 20:54:17.562: I/Timeline(8935): Timeline: Activity_idle id: android.os.BinderProxy@36e5dd2e time:5498175
11-09 20:55:55.167: V/ActivityThread(8935): updateVisibility : ActivityRecord{1892328c token=android.os.BinderProxy@36e5dd2e {com.embarcadero.delphiteste/com.embarcadero.firemonkey.FMXNativeActivity}} show : true
I’ve snipped some unimportant parts from the log you provided. It appears to be normal, however it is odd that there’s no messages at all regarding the token. Can you set up a filter so that it shows only messages from the application? (as per the instructions I linked to), and can you make sure that the code on line 87 in MainFrm.pas is being executed (i.e. FFCM.RequestAuthorization), as well as line 100? (FFCM.Connect)
Dave,
The function AResults.AreAllGranted result false, dont run FFCM.RequestAuthorization in line 86 (MainFrm.pas).
I’ve modified this file:
https://github.com/DelphiWorlds/KastriFree/blob/master/Demos/FCMRevisited/MainFrm.pas
So that it does not request permissions, as they’re really only optional in this demo. If you update that file, can you let me know whether the FCMAuthorizationResultHandler method is called, and whether FFCM.Connect is called?
Dear Dave,
It worked on Android with main:
constructor TfrmMain.Create(AOwner: TComponent);
begin
inherited;
FFCM := TFirebaseMessaging.Create;
FFCM.OnAuthorizationResult := FCMAuthorizationResultHandler;
FFCM.OnTokenReceived := FCMTokenReceivedHandler;
FFCM.OnMessageReceived := FCMMessageReceivedHandler;
FRequester := TPermissionsRequester.Create;
FRequester.OnPermissionsResult := RequesterPermissionsResultHandler;
FRequester.RequestPermissions(cDangerousPermissions, 1);
end;
The initialization error was due to an incorrect character in the strings.xml file.
I’m going to test on iOS now.
Congratulations on your code and thank you very much for your attention.
Best wishes.
Dave, the FFCM.Connect function is called, displays the port number in the app, but does not call the function to get the Token number.
I will test on another computer with another install of Delphi and then I’ll give you the result, it was supposed to have worked.
Hi, Dave.
I am with a new computer and with a new Delphi installation. I downloaded the demo and changed the DW.Firebase.Messaging.Android.pas file as you passed.
He also returned the error:
‘Java.lang.IllegalStateException: Default FirebaseApp is not initialized in this process com.embarcadero.delphiteste. Make sure to call FirebaseApp.initializeApp (Context) first. ‘
I am testing on another computer with another Delphi installation, as I did several tests with examples and components and I may have compromised the default configuration.
Hello, Dave.
On Android everything worked out, now I’m testing on iOS.
What I did wrong, because when I compile returns the error:
[DCC Error] E2597 ld: warning: directory not found for option ‘-FC: \ Users \ danny \ Documents \ Embarcadero \ Studio \ SDKs \ iPhoneOS11.2.sdk \ System \ Library \ PrivateFrameworks’
ld: file not found: /System/Library/Frameworks/SystemConfiguration.framework/SystemConfiguration
[DCC Fatal Error] F2588 Linker error code: 1 ($ 00000001)
Refer to section 3, here:
http://delphiworlds.com/2017/05/adding-firebase-cloud-messaging-mobile-apps-part-2/
i.e. ensure that you add the required frameworks in the SDK manager
In the demo (FCMRevisited) that I’m testing, you already have the Firebase SDK files.
.. \ .. \ ThirdParty \ Firebase \ iOS \ Firebase.5.5.0 \ Analytics \ FirebaseAnalytics.framework;
.. \ .. \ ThirdParty \ Firebase \ iOS \ Firebase.5.5.0 \ Analytics \ FirebaseCore.framework;
……..
……..
Please read section 3 of the link I gave, i.e. the one with the heading “Add the required frameworks from the iOS SDK to the Delphi SDK Manager”
The link is broken.
If you’re not familiar with how to add other frameworks to the iOS SDK, you can refer to this article. You will need to add each of the following frameworks:
http://blog.delphiworlds.com//2013/10/adding-other-ios-frameworks-to-the-sdk-manager/
I’ve fixed the link now, which is:
http://delphiworlds.com//2013/10/adding-other-ios-frameworks-to-the-sdk-manager/
I have installed the required SDK frameworks as below:
http://www.servidorse.com.br/_temp/framework.png
Now it returns the error:
[DCC Error] E2597 ld: framework not found ImageIO for architecture arm64
[DCC Fatal Error] F2588 Linker error code: 1 ($00000001)
If you’ve imported the iOS 11.3 SDK, you may be able to use the ImageIO framework from there in the iOS 11.2 SDK (which it seems to be missing from in some cases; I don’t know why)
To do that, copy the ImageIO.framework folder from:
C:\Users\(username)\Documents\Embarcadero\Studio\SDKs\iPhoneOS11.3.sdk\System\Library\Frameworks
Into:
C:\Users\(username)\Documents\Embarcadero\Studio\SDKs\iPhoneOS11.2.sdk\System\Library\Frameworks
Then rebuild the demo. You may have already discovered that the demo will not compile against the iOS 11.3 SDK (or later). Hopefully this will be rectified in the next version of Delphi
Thanks for the answers, you’re helping me a lot.
I do not have iOS 11.3 SDK installed because it does not run in Delphi. I will install it on another computer and copy the ImageIO.framework file.
Dave,
He also asked for the IOSurface framework, I did the same procedure and ran it on iOS.
Thank you for your help and attention.
Congratulations again for your code.
Best wishes.
Hi Dave,
Thank you for your great tutorial.
I have implemented the demo project and it runs well on Android 8 SDK 26.
Can you please explain why this app runs correctly without setting up notification channels which are required by Google?
Thanks
Hi Nobby,
Thanks! The implementation here does actually use a notification channel, named “default”. It’s in the Java code, here:
https://github.com/DelphiWorlds/KastriFree/blob/master/Java/DWNotificationPublisher.java
In the initialize method at line 33, and the channel is assigned to the notification at line 129. I have a plan to modify the code so that users can set up their own channels, however I have a bunch of other commitments at the moment.
Hi there,
I’m having issues getting the app to work on iOS again, still using iOS 11.2.
The app crashes on the startup, with the message “Couldn’t find Objective-C Class “UNUserNotificationCenter””.
I tried resetting everything but the Delphi installation itself, meaning I reinstalled xCode, the Project is as clean as it comes and the SDK is also straight from the new xCode 9.2 (iOS 11.2) installation.
Do you have any Idea how I could go about this problem?
Greetings and thank you for all your amazing work, not just on the notifications.
Hi Cisc,
Thanks! Have you made sure that you’ve followed parts 2 and 3 of this article?:
http://delphiworlds.com/2017/05/adding-firebase-cloud-messaging-mobile-apps-part-2/
Hi Dave, thank you for the reply.
After checking again and not finding anything I went searching for the “UNUserNotificationCenter”-Class. Apparently it’s only supported in iOS10+ Devices, while I was using a iOS 9.5 iPad because I temporarily did not have access to my up to date iPhone.
So, completely my fault. It’s working on the iOS 12 iPhone. Thank you for your reply.
Dave,
Which parameters of the strings.xml file are used for FCM registration (get FCM token for Android)?
Pretty sure the one that matters for FCM is gcm_defaultSenderId. You could always try leaving just that entry in strings.xml 🙂
Hey Dave!
I finally have FCM working on Android/iOS for my App using KastriFree thanks to your help and this forum. I do have a question however. How would I go about allowing a toggle within the application to allow or dis-allow push notifications?
My guess since the device can receive notifications even when the app isn’t running is a call to de-register would need to be made. If that mechanism is Unsubscribing from a channel, what string value is supplied as the default channel? If I am incorrect, please point me in the right direction.
Kindly,
Mike
That’s a good point, Mike; it would need changes to both the Delphi and Java code.
I’ll add it to the to-do list. Hopefully I’ll be able to do something about it in the next couple of weeks.
Hey Dave!
What ABSOLUTE changes would be required to move a (functional) app using KastriFree for notifications and permissions API26+ in the case the version of DELPHI moved from 10.2.3 to 10.3. I emphasize “ABSOLUTE ” only because I understand some items may be optional.
I’ve assumed:
1 – Get latest version of Kastrifree from Github with 10.3 mods.
My app when compiled for ANDROID on Rio 10.3… with NO changes asks for the permissions and hangs on a black screen. Before I dig into the code, I wanted to know what certain changes must be effected if you already have an idea.
Kindly,
Mike
UPDATE: While I still would like to know any recommended ideas, my issue is not as it seemed. I was testing my App (ANDROID/IOS DATASNAP REST CLIENT) but failed to recompile the DATASNAP server app under 10.3. Apparently this step is necessary even with NO code changes.
Kindly,
Mike
Firstly a big thanks to Dave for supply the Kastri libraries – it has proven to be an extremely useful library given some of the shortcomings befalling the Android stream.
For reference the issues reported earlier by Fernando/Stanislav in regards to push notifications on Android not being processed properly with the apps in the background still persist on Android 8.0.0 & Delphi 10.3. Seems to work fine on earlier versions of Android but I am yet to test on a device running 8.1 but hopefully will do later today. Same issue occurs with supplied demo app and an updated app.
Extract from logcat:
—–
12-05 09:07:14.367 E/FirebaseMessaging(10421): Caused by: java.lang.ClassNotFoundException: Didn’t find class “com.google.firebase.messaging.R$string” on path: DexPathList[[zip file “/data/app/com.intov8.CorvusWall-0CX9pRfv8rUIyRxdy-6wGw==/base.apk”],nativeLibraryDirectories=[/data/app/com.intov8.CorvusWall-0CX9pRfv8rUIyRxdy-6wGw==/lib/arm, /data/app/com.intov8.CorvusWall-0CX9pRfv8rUIyRxdy-6wGw==/base.apk!/lib/armeabi-v7a, /system/lib, /vendor/lib, /product/lib]]
12-05 09:07:14.374 E/NotificationService( 1606): No Channel found for pkg=com.intov8.CorvusWall, channelId=null, id=0, tag=FCM-Notification:16825535, opPkg=com.intov8.CorvusWall, callingUid=10136, userId=0, incomingUserId=0, notificationUid=10136, notification=Notification(channel=null pri=0 contentView=null vibrate=null sound=content://settings/system/notification_sound defaults=0x0 flags=0x10 color=0x00000000 vis=PRIVATE)
—–
I’ve tried all of the suggestions with no luck to date. If anyone has managed to work this one out it would be good to know how to resolve.
Dave,
My project has been fine over the last month or so with notifications working as expected. Last night I was preparing a release for The Google Playstore and somehow the project got corrupted. I put it back in order however, now on Android (still 8.0) using SDK 25.2.5, when the app is running, I do not receive the notifications. I do however get the payload in FCMMessageReceivedHandler. If I close the app, I get notifications just fine. Are you able to determine based on that what’s broken?
Kindly,
Mike
Dave,
Nevermind. Maybe I just didn’t notice all this time. I modified Line 138 of DW.Firebase.MessagingAndroid.pas so it behaves as it does on iOS. Is this by design that the notifications don’t work when the app is in the foreground?
Kindly,
It was by design, to mimic what I thought was standard behaviour in iOS. Turns out it wasn’t; rather a bug in the Delphi code. I will change it so that the notification is sent
Dave,
Thanks for your response. I am noticing that by removing the aforementioned condition on line 138 of [DW.Firebase.MessagingAndroid.pas], the app fires an empty Notification on startup. Is there any way to prevent that?
Kindly,
Mike
Hi Mike,
Regarding showing notifications on Android when app is active.
My resolution for this is to revert the last commit of line 138.
In the ‘OnMessageReceived’ event of TFirebaseMessaging, create a TNotification (System.Notification) object (only Android, as iOS handles this itself). Create a NotificationCenter (I have a component on designtime) and add the own created notification to the NotificationCenter (NotificationCenter.PresentNotification(LNotification)).
Note that you have to detect if the notification comes in while running the app, or if the notification comes in while the app was closed (so the notification starts the app).
I’ve now checked in a change for DW.Firebase.Messaging.Android that should fix the issues introduced by the last commit, plus an existing issue:
The app should no longer publish a notification for a “non-message” intent, and no longer publish another notification when the app is being started from tapping on a notification
This change looks nice Dave, thanks!
Working nicely,. Thanks!
Hi Mike, Dave. (Fernando and Alex)
I’m still experiencing the Android 8.0 + exception when receiving messages when the app is closed (java.lang.ClassNotFoundException: Didn’t find class “com.google.firebase.messaging.R$string”).
@Mike, have you solved this for yourself as stated in this blog on September 11, 2018 at 10:52 pm?
It’s working on lower Android and iOS. But for a live solution I need to have support for Android 8.0 and higher as well.
My system:
Delphi 10.2.3
SDK: 25.2.5
Current master repository of Kastrifree library.
I’m sending JSon by my own server to https://fcm.googleapis.com/fcm/send.
Using an Authorization:key in the headers and a ‘to:’ part in the JSon to send the message to a specific device.
I’ve already tried to:
– enable the ‘notification channel id’ config in the AndroidManifest.template.xml
– send the channel ‘default’ with my JSon ‘notification’ object.
Any help is very appreciated!
Greetings and my apologies for the delay:
I solved this issue by using DeployMan. There are way too many folders and file to specify a proper deployment configuration so you are likely missing some files. Look in the FCM Revisited posts and search for the keyword “Deployman”. Follow the associated instructions and your issue will likely be resolved.
Let me know if you can’t track down the post.
Kindly,
Mike
That’s would be great! I’ll keep you posted.
Great!
My Kastrifree Base is as follows:
C:\Delphi Addons\KastriFree-master\ThirdParty\PlayServices\Android\res
The path from ThirdParty\playServices\Android\res need to be copied to the remote ./res folder and there are many files so deployman makes this simple. I think you will have success after that, but I’m willing to add any help I can.
Kindly,
Mike
Unfortunately, I’m still experiencing the same problem.
01-07 09:14:56.621: W/FirebaseMessaging(13610): Missing Default Notification Channel metadata in AndroidManifest. Default value will be used.
01-07 09:14:56.625: E/FirebaseMessaging(13610): Error while setting the notification channel
01-07 09:14:56.625: E/FirebaseMessaging(13610): java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/firebase/messaging/R$string;
01-07 09:14:56.625: E/FirebaseMessaging(13610): at com.google.firebase.messaging.zza.zzn(Unknown Source:195)
01-07 09:14:56.625: E/FirebaseMessaging(13610): at com.google.firebase.messaging.zza.zzh(Unknown Source:310)
01-07 09:14:56.625: E/FirebaseMessaging(13610): at com.google.firebase.messaging.FirebaseMessagingService.zzd(Unknown Source:261)
01-07 09:14:56.625: E/FirebaseMessaging(13610): at com.google.firebase.iid.zzg.run(Unknown Source:26)
01-07 09:14:56.625: E/FirebaseMessaging(13610): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
Even the demo project FCMRevisited does have this same error. So, only on my Samsumg Android 8.1 device. All Android devices I have with lower Android version are going fine.Only faulting when app is closed, so the service has to do it’s thing.
The demo is working OK for me on both of my Android 8.1 devices, so not sure what I can do here – has me beat 🙁
Hi Dave, thank you for the response. Now finally I’ve figured something out now I knew it could work.
The problem is in the JSon notification.
I’ve added a ‘notification’-part to the message. This contains a body, title and sound (S[‘sound’] := ‘ default). I’ve introduced it to let the incoming message ‘beep’ as configured on the device.
When I leave this ‘notification’ part away from my message, it suddenly works on Android 8.1!
I’ll investigate a little further..
For the time being I will not send a ‘notification’ data-element in JSon anymore.I’ll first test if the current situation works well with my clients.
For iOS however I had to re-enable the ‘notification’ data-element in the JSon to let the pushmessages come through. So my pushmessage-send-server will send a different JSon for iOS-registrered tokens comparing to Android registered tokens.
Dave,
Just asking out of curiosity what’s the gameplan for iOS come March 2019 with regard to FCM Support in KastriFree? I understand the Apple App Store requirement will be that SDK 12.x must be targeted. I haven’t had success beyond SDK 11.2 with the library.
I’d like to plan properly since my current App store release is dependent on the library presently.
Kindly,
Mike
Unfortunately, the kind of issue that exists with iOS 12 SDK and Firebase is out of my hands, i.e. it’s something that needs to be resolved by Embarcadero (or at least appears to be)
This report relates to the issue: https://quality.embarcadero.com/browse/RSP-22154
Thanks for the heads-up about the date, though
Hello Dave,
thank you very much for the demo project. It works very well in general. I am using RAD Studio 10.3, my Android device is 7.1.1. I did all the configuration steps, the app is running and it receives a device token.
The problem appears when I send a notification via Firebase Cloud Messaging to this device token. The app is being closed on the phone with a message ‘Unfortunately app has stopped’ (I hope this is the message in English – in German it says ‘App wurde beendet’). When the app is running in the background or the app has been closed the same thing happens.
Do you have an idea where the problem is located?
Thanks very much
Matthias
Hi, Dave
Great Demo, 10x a lot.
Have a question, how did you get android Device ID ?
As I know it is required for FCM initialization.
Thanks very much
Dobrys
The Android device id is not required for FCM initialization. Perhaps you’re referring to the device token? That is all handled by the Firebase SDK for Android.
If you are actually referring to the device id, there’s a function called GetUniqueDeviceID in the TOSDevice record contained in this unit:
https://github.com/DelphiWorlds/KastriFree/blob/master/Core/DW.OSDevice.pas
For Android, it uses the GetUniqueDeviceID function in TPlatformOSDevice in this unit:
https://github.com/DelphiWorlds/KastriFree/blob/master/Core/DW.OSDevice.Android.pas
Please note the warning in the source code, about the value returned.
Hi Dave,
I used the FCM with this post on Delphi 10.3 well.
but, now I upgraded delphi 10.3 to 10.3.1, I have a error message.
Default FirebaseApp is not initialized in this process com.delphiworlds.test. Make sure to call FirebaseApp.initializeApp(Context) first.’. Process FCMRevisited.apk (30219)
I tested ‘FCMRevisited’ Demo project..
Thank you.
Hi Joana,
More than likely your strings.xml is missing from the Resources folder in the demo. Please note however that I am having trouble running the demo on Android 9. It works OK on Android 8.1
Thank you Dave,
It works fine.
FYI
– Mobile : Android 8.1
Thanks again!
Hi Dave,
when the app is closed, is it possible to open Activity without clicking notification.
Thank you.
Hi Nicolas,
It would be possible with further changes to the Java code (it is not something that can be done inside the Delphi code). I may have time to look at this in the next few days.
Hi Dave,
Ok thank you,
I upgraded delphi 10.3 to 10.3.1
I use FCMRevisited for push notification management and it works fine.
Give me the news please.
Thank you.
Hi Dave,
I modified the dw-firebase.jar file to include a launchintent.
So I have no problem.
thanks again.
I’ll be looking at making this change anyway, however that’s excellent news!
Hello,
First of all thanks for sharing your work and keeping it up to date.
I am trying to use push notifications it with Rio. KastriFree commit version is ce2b370 (yesterday).
No problem with Android 8.0 and Android 8.1 version devices. However, I have a crash for Android 6.0 device that I cannot get a log (device is my friend’s). Device can receive push message when application has focus. Crashes when in the background.
I also have a crash for Android 4.4.2 device. When app is in the foreground, push notification details shown in “FCM Messages” part in the memo. However, no push notification displayed on the phone. No log entries recorded for that, too. When in the background, crash reported and I read below log entries.
03-29 10:53:45.926: V/ApplicationPolicy(2434): isApplicationStateBlocked userId 0 pkgname com.embarcadero.test
03-29 10:53:46.026: I/WindowState(2434): WIN DEATH: Window{4241f818 u0 com.embarcadero.test/com.embarcadero.firemonkey.FMXNativeActivity}
03-29 10:53:46.031: W/WindowManager(2434): Force-removing child win Window{43182238 u0 PopupWindow:42371758} from container Window{4241f818 u0 com.embarcadero.test/com.embarcadero.firemonkey.FMXNativeActivity}
03-29 10:53:46.031: W/WindowManager(2434): Force-removing child win Window{42eebd38 u0 SurfaceView} from container Window{4241f818 u0 com.embarcadero.test/com.embarcadero.firemonkey.FMXNativeActivity}
03-29 10:53:55.816: E/AndroidRuntime(23127): Process: com.embarcadero.test, PID: 23127
03-29 10:53:57.616: D/CrashAnrDetector(2434): processName: com.embarcadero.test
03-29 10:53:57.616: D/CrashAnrDetector(2434): broadcastEvent : com.embarcadero.test data_app_crash
03-29 10:54:00.896: D/PowerManagerService(2434): [api] handleWakeLockDeath : release WakeLock : PARTIAL_WAKE_LOCK ‘wake:com.embarcadero.test/com.delphiworlds.kastri.DWFirebaseMessagingService’ (uid=10218, pid=23127, ws=null) (elapsedTime=5211)
03-29 10:54:00.896: I/ActivityManager(2434): Process com.embarcadero.test (pid 23127) (adj 8) has died.
I have not seen this error posted in all above comments so here it goes.
I appreciate any help.
Thanks & regards.
Update,
1) When application has focus:
I get following error in Delphi when app running in debug and has focus:
First chance exception at $6173DA7D. Exception class EJNIException with message ‘java.lang.NoClassDefFoundError: android.app.NotificationChannel’. Process FCMRevisited.apk (14516)
That raises from DW.Firebase.Messaging.Android.pas around line 188:
TJDWNotificationPublisher.JavaClass.sendNotification(TAndroidHelper.Context, data, True);
This however does not couse application to crash.
2) when application in the background:
Same as above.
3) when application is not running at all: App does crash
Hi Ertan,
I’ve just pushed an update that should fix the issue. Unfortunately, at present I don’t have a device that I can test this on, so I’m “flying a little blind”.
You’ll need to update this file:
https://github.com/DelphiWorlds/KastriFree/blob/master/Lib/dw-firebase.jar
..and do a clean/build
Hi Dave,
Problem solved. Android 4.4, Android 6.0.3, Android 8.0, Android 8.1 all can receive push notifications just fine. Both when app in the foreground or in the background.
Thank you.
I seemingly having a problem when using push notifications and maps service together. As notification solution needs some libraries disabled in project, I get error when I create my form with TMapView and TLocationSensor components in it.
Error message reads: java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/android/gms/common/internal/zzx;.
I wonder if there is a workaround.
Thanks.
Unfortunately MapView is not compatible with newer versions of Google Play Services. It’s something I’ve meaning to look at for a while now
I do not know if KastriFree includes MapView of its own. On the other hand, default MapView in Rio works out of the box. I have designed and coded my map related form in a separate app. That separate app is just fine and is running as expected with markings, circles and everything.
Do you know if another map solution which can be used together with KastriFree? TMS has one as to my knowledge. I am not sure if its compatible though.
Hi Ertan,
I have devised a patch that may solve the MapView issue. Can you let me know if you are interested in testing it out?
Hello Dave,
I would like to test it for sure. Is it committed in GitHub? How should I test it for you? I mean do you have any preference?
Thanks.
I confirm that TMSFMXWebGMaps components run together with this push message solution just fine.
I need to do the same process with .aar from https://github.com/pagseguromaster/plugpag is it possible using your tools?
You can use the Android Tools\Extract AAR Files function of the Codex tool: http://delphiworlds.com/codex/ to extract the .jar file from the .aar file, and use the Android Tools\Java2OP function to generate a Delphi unit for the .jar. Please be aware that Java2OP does not always generate the code accurately.
Hello, Dave. Thank you for the article. I am experiencing some issues when I try to receive a notification when the application is in the background (not killed) on android >=8. I’ve read a lot about the new notification channel requirement for android 8 and above. The problem is that I’ve done everything described on the net (adding dependencies in strings.xml, AndroidManifest.xml and etc). The only problem that still persists is that an R$string.class is missing in the firebase-messaging.jar that I am using – the one from your demo project with version 17.1.0. The problem is that the aar to .jar converters (even your tool) doesn’t implement all the need resources in order the .jar to be fully functional and that R$string.class file that I miss is the problem I am experiencing. My question is – how to implement this file into the jar file? There is an R.txt file in the .aar archive which should be converted and implemented but that doesn’t happen.
Hi Alex,
Can you provide the *exact* error message that you receive? If it’s similar to this:
09-09 18:34:23.439: E/FirebaseMessaging(23574): java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/firebase/messaging/R$string;
I’m afraid I still don’t have an answer as to why that happens. It appears related to Android 8.0 (as opposed to 8.1)
Hello Dave,
It’s the exact same error. And yes -it appears on Android 8 and 9 only. The error is related with the notification channel requirement of Firebase. Apparently there is no fix for it at the current moment. Is there anyway to create and integrate the R$string.class file and is the R.txt file in the firebase-messaging-XXXXX.aar related to that .class file?
The R.txt file contains the following: int string fcm_fallback_notification_channel_label 0x1
Hi Alex,
Looking back at some of the earlier comments, your issue may lay with the Project Deployment. Please ensure you download a copy of the original demo:
https://github.com/DelphiWorlds/KastriFree/tree/master/Demos/FCMRevisited
and check if that works for you. If it does, then verify the deployment is correct in your real project. Note: There a lot of files in it. Other than that, I don’t know what might be causing it.
Hi Dave, I’m having an issue where on my on my iOS app able receive push notification but not able to receive the payload message. However, my Android app is receiving both push notification and payload message as expected. Do you know what might went wrong? Thanks!
Hi Chris, I’ve recently updated the code to resolve this problem. You’ll need to re-download the Kastri Free library, or do a pull if you’re using a Git client.
Thanks for the update Dave. I’ve tested the latest Git code (FCM Revisisted demo) on my iOS device and I can received the payload message but now there is no push notification message and sound. Strange thing is I can receive the push notification if I install the new demo without uninstalling the old demo first. Are you able to replay the same issue?
Hi Chris,
Yes, my latest fix actually broke apps that have not been installed yet. I’ve now checked in changes to Features\DW.Firebase.Messaging.pas and Features\DW.Firebase.Messaging.iOS.pas that should finally fix the issue.
Hi Dave,
I downloaded all your files two weeks ago again in order to update any changes made by you. I verified all the instructions many times to be sure that I don’t miss something. Unfortunately the problem still persists on your demo project on the first place and on ours as well. It would be great if some of the people from the comments who faces the same error before tell if they somehow fixed the issue.
Same error in here. I tried several clean install both delphi and firebase. clean download all codes from github.Getting same error.
Only difference is that when I run the demo with “Entitlement List/Maps Service” checked (which is coming default on demo) Im getting “Unable to create process: Performing Streamed install”.
When I unchecked this option, demo is working when application open. Getting test push notifications. When app closed or running in background, there is no notifications.
I gave almost all permissions to app,still no chance.
I also upgrade my android device v8 to v9. Still same.
on android log, same error as you mentioned above.
java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/firebase/messaging/R$string;
The question is, did you solve this problem ? If so how ?
Thanks,
Hi, Dave.
Many thanks for the blog and help you provide.
I have a problem I did not have before. Recently started.
While attempting to give the POST for push notification for iOS mobiles,
I get the following answer:
{
“multicast_id”: 8386050816319681871,
“success”: 0,
“failure”: 1,
“canonical_ids”: 0,
“results”: [{“error”: “InvalidRegistration”}]
}
The token appears to have been successfully registered, as per your example.
At least returns that was registered.
I use Delphi 10.2.3.
What could be happening?
Did the changes on Google cause incompatibility with the token registration?
Thanks for listening.
Ricardo
Hi Ricardo, That problem is usually because the wrong value is being used for the token when sending the push message. Ensure you are using the correct server key from Firebase Console for your project
Hi Dave,
I greatly appreciate your guides on this topic and your responses for people asking for help.
However, I am stuck when trying to run the demo app with the same error others had, too (“EJNIException: java.lang.IllegalStateException: Default FirebaseApp is not initialized in this process com.delphiworlds.test. Make sure to call FirebaseApp.initializeApp(Context) first”).
I tried your suggested solutions (applying a fix to DW.Firebase.Messaging and checking the strings.xml), but without success. I tested it on Android 7.1.1 and multiple Android 9 devices.
Do you have any other ideas as to how I can approach to fix this?
I’m not sure what is causing that; it works fine for me.
I’m working on a “revisitation” of the revisit to update it to Delphi 10.3.2, so perhaps that might solve it. Stay tuned!
Thank you for your quick response
Did you convert the generated google-service.json file from the firebase console to strings.xml file and deploy it in the project ?
I had the same error because my strings.xml was in the wrong folder and my project was not finding it. I am pretty sure that’s where your problem is.
[…] solution is based around existing code that is used in my FCM solution, presented here. I created a unit (DW.PushNotification.iOS) which is similar to FMX.PushNotification.Android, that […]
[…] This article has been revisited, here. Please read that article as the code has now been updated to use that […]
Hi Dave, first of all, thank you for your amazing job.
I hope you can help me out.
I have been working with both examples FCMRevisited and EMBTFCMv2.
With EMBTFCMv2 I have been able to get the token and receive push notifications only on Android Device however on IOS the example hangs when you open the app.
With FCRevisited on Android the app crashes in the beginning however I have been able to receive pus notification, but ONLY with the app opened and the messages are received in the memo, but I can not get the notification icon. When the app is closed nothing happens.
Thank you for your time.
Finally, I have been able to do on Android and IOS. Thanks.