/, General tips/Firebase Cloud Messaging, revisited

Firebase Cloud Messaging, revisited

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, so that the necessary “dangerous” permissions are handled.

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.

By |2018-09-06T12:18:03+00:00August 12, 2018 5:41 pm|Code tips, General tips|68 Comments

About the Author:

68 Comments

  1. Fernando Celio Leal August 17, 2018 at 8:31 am - Reply

    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

    • Dave August 17, 2018 at 8:41 am - Reply

      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.

      • Gabriel Tavares October 11, 2018 at 8:14 am - Reply

        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.

        • Dave October 11, 2018 at 9:57 am - Reply

          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

  2. Fernando Celio Leal August 20, 2018 at 11:42 am - Reply

    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

    • Dave August 20, 2018 at 11:45 am - Reply

      What platform is this on? How are you sending the message, and what is the payload?

      • Fernando Celio Leal August 20, 2018 at 11:54 am - Reply

        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

        • Dave August 20, 2018 at 12:02 pm - Reply

          What happens if you send a message using the method described after section 10, here?:
          https://www.delphiworlds.com/2017/05/add-firebase-cloud-messaging-mobile-apps-part-1/

          • Fernando Celio Leal August 20, 2018 at 12:04 pm

            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.

          • Dave August 20, 2018 at 12:48 pm

            I might have broken something.. I’ll check in a few hours

          • Fernando Celio Leal August 20, 2018 at 12:47 pm

            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”
                     }
                 ]
            }

          • Dave August 20, 2018 at 9:10 pm

            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.

          • Fernando Celio Leal August 20, 2018 at 9:52 pm

            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!

          • Dave August 20, 2018 at 10:02 pm

            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

          • Fernando Celio Leal August 20, 2018 at 10:04 pm

            Android 8.0 Samsung S8 +

          • Fernando Celio Leal September 5, 2018 at 9:31 am

            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

          • Dave September 5, 2018 at 10:29 am

            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)

          • Fernando Celio Leal September 5, 2018 at 11:21 am

            The only exception I have is that if I disable google-analytics-v2.dex.jar my application hangs at startup.

          • Fernando Celio Leal September 5, 2018 at 11:29 am

            actually hangs when I leave the cloud-messaging.dex.jar file disabled

      • Dave August 20, 2018 at 10:15 pm - Reply

        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

    • Stanislav Ihnatovich August 20, 2018 at 4:43 pm - Reply

      Same problem on Android 8.

  3. Nico Gelinas August 28, 2018 at 4:49 am - Reply

    Hi Dave!
    First of all, thanks for the post. Did you follow this post?

    Thank you

    • Dave August 28, 2018 at 6:39 am - Reply

      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.

  4. Chris September 3, 2018 at 3:41 am - Reply

    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.

    • Chris September 3, 2018 at 3:44 am - Reply

      btw, I’m on Android 7.1.2

    • Dave September 3, 2018 at 7:54 am - Reply

      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.

      • Chris September 4, 2018 at 8:23 am - Reply

        I found the mistake, I inserted the values in strings.xml at the wrong place

  5. Chris September 4, 2018 at 8:39 am - Reply

    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?

    • Chris September 4, 2018 at 8:52 am - Reply

      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

      • Dave September 4, 2018 at 9:11 am - Reply

        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

        • Chris September 5, 2018 at 7:26 am - Reply

          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

          • Dave September 5, 2018 at 7:37 am

            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”
            }
            }

          • Chris September 6, 2018 at 6:09 am

            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?!?

          • Dave September 6, 2018 at 9:16 am

            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.

          • Chris September 6, 2018 at 10:06 am

            Good idea to keep track of the token and update the server.
            You got 2 beer (at least in Austria it would be 2) 🙂

          • Dave September 6, 2018 at 11:15 am

            Thanks!! It’ll be about 1.5 beers here 😉

  6. Fernando Celio Leal September 6, 2018 at 12:59 pm - Reply

    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

  7. Nico Gelinas September 7, 2018 at 12:36 am - Reply

    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

  8. Dave September 7, 2018 at 8:59 am - Reply

    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

  9. Mike September 10, 2018 at 3:35 am - Reply

    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?

    • Dave September 10, 2018 at 7:35 am - Reply

      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: https://www.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

      • Mike September 10, 2018 at 9:07 am - Reply

        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

        • Dave September 10, 2018 at 10:19 am - Reply

          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.

          • Mike September 10, 2018 at 1:14 pm

            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.

          • Mike September 10, 2018 at 1:20 pm

            I also wanted to ask what’s the earliest version of Delphi the Kastri Library will work with?

          • Dave September 10, 2018 at 1:45 pm

            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

          • Mike September 11, 2018 at 10:52 pm

            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).

  10. Graham Murt September 10, 2018 at 6:18 pm - Reply

    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!

    • Dave September 10, 2018 at 8:43 pm - Reply

      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:

      https://www.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!

      • grahammurt September 10, 2018 at 9:01 pm - Reply

        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!

      • grahammurt September 10, 2018 at 10:15 pm - Reply

        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.

    • Mike September 10, 2018 at 8:48 pm - Reply

      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.

      • grahammurt September 10, 2018 at 8:57 pm - Reply

        Thanks Mike, tried this but no change. Going to test with hUrl as Dave suggests. Thanks again!

        • Pieter Bas Hofstede September 11, 2018 at 5:31 pm - Reply

          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).

  11. Mike September 10, 2018 at 8:49 pm - Reply

    My apologies! Dave already responded. Just offering something in case you were idle.

  12. Pieter Bas Hofstede September 12, 2018 at 7:37 pm - Reply

    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!

    • Dave September 12, 2018 at 9:39 pm - Reply

      You may be missing the -ObjC linker option as per section 2, here: https://www.delphiworlds.com/2017/05/adding-firebase-cloud-messaging-mobile-apps-part-2/

      • Pieter Bas Hofstede September 12, 2018 at 10:11 pm - Reply

        Thanks a lot Dave, this solved it!

      • Mike October 2, 2018 at 2:37 am - Reply

        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?

        • Dave October 2, 2018 at 9:00 am - Reply

          No, it won’t work on iOS Simulator, since push notifications are not possible on Simulator

  13. Mike September 13, 2018 at 10:17 pm - Reply

    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

  14. Mike September 14, 2018 at 1:39 am - Reply

    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)

    • Alex September 14, 2018 at 5:17 am - Reply

      Hi Mike. You’ll want to revisit steps 7 and 8 from the old FCM demo, part 1:
      https://www.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.

      • Mike September 14, 2018 at 7:51 am - Reply

        Thank you! I’ll bang at it.

  15. Stephane Barré September 26, 2018 at 1:47 am - Reply

    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.

  16. Juan Martinez October 5, 2018 at 11:03 pm - Reply

    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.

    • Delphi Worlds October 9, 2018 at 11:52 am - Reply

      Hi Juan,

      Without seeing the code, I really couldn’t say what the problem is

Leave a Reply

Show Buttons
Hide Buttons