NOTE: This article has been revisited, here. Please read that article as the code has now been updated to use that method.
Firebase Services from Google are becoming very popular, and Firebase Cloud Messaging (FCM) is just one part of it. In this article I show how you can incorporate support for FCM in your Delphi apps for Android and iOS.
Firstly, some acknowledgements: Many thanks to Stephane Vanderclock (aka Loki) from whom I gleaned much information, for the countless late nights he spent tearing his hair out working out how to make this all work, and for the code he wrote (which you can find here) which I’ve based almost all of my work on. Thanks also to Steven Chesser who was a willing guinea pig, and who is also thankful to Stephane and myself for probably saving his job, and thanks to Allen Drennan and company from Grijjy, for their amazingly excellent blog articles (particularly this one, from which this article is partly based) and their tools (one of which is used for this article).
Secondly, a few caveats: This article and the accompanying code is close to the bare minimum for incorporating Firebase Cloud Messaging. Stephane and I are not exactly experts in Firebase Cloud Messaging, and this implementation doesn’t pretend to cover everything. The Firebase libraries contain a number of other services (such as Firebase Crash, Analytics etc) that are not used by the code presented here: a future article may include how to use these. Also, the message payload that is passed to the OnMessageReceived event is completely raw: it is left up to the reader as to how the data might be dealt with when a notification is received while the app is running. Most importantly however, is that (as per step 9) this implementation requires that you disable all of the Google Play Services that Delphi adds automatically, so if your app relies on any of these, they will not work.
Thirdly, because this article grew a lot after I started it, I’ve decided to split it into two. This first part, although there are some pointers related to iOS, will feature Android, and iOS will follow shortly in part 2.
Fourthly, this article heralds the release of the free version of the Delphi Worlds “Kastri” library, which includes the framework for Firebase Cloud Messaging support, and the starter project which you will find in the demos folder. More features and demos will be added to this free library in the future, and the commercial version of the library will be released in the next few weeks.
Last of all: I used Delphi 10.2 Tokyo for this project, however it also works with at least Delphi 10.1 Berlin.
Let’s start!
1. Creating a project in Firebase Console:
If you’ve never used Firebase before, the first thing you’ll want to do is to create a project in the Firebase console. Google provide some how to’s on YouTube for Firebase, so you might want to check them out. I recommend watching the one for iOS first, and pay attention up to the 2:23 mark, as the rest is specific to Xcode. Next, watch the video for Android, paying attention to the following sections: 0:59 – 1:14, 1:43 – 2:44, 2:59 – 3:03 and 3:46 – 4:04
If you already have a project set up for iOS and Android, you’ll need to download the files (if you haven’t done so already) that have information about your app, for the specific platforms. The one for iOS is GoogleService-info.plist. Please refer to the following images as to where in Firebase console you’ll need to download it from:
The file for Android is google-services.json:
Later you’ll be using these files in your project.
2. Download the required packages using the Android SDK Manager
The Android version of Firebase requires two packages that can be downloaded using the Android SDK Manager, which can be found at the root of the Android SDK installed on your system. If you opted to install the Android SDK with Delphi, it will be located in the folder:
C:\Users\Public\Documents\Embarcadero\Studio\xx.0\PlatformSDKs\android-sdk-windows
Where xx refers to the version of BDS on your system. Run SDKManager.exe, and scroll down to the Extras section in the list of packages. There you will see Android Support Repository and Google Repository:
Select these two packages and click Install, then accept the license agreements and the packages will install. These packages contain files in .aar format, which are really just .zip files.
In order to make it easier to extract the required files from these packages, I have developed a tool called ACTED, which stands for Android Companion Tool Enhancing Delphi, and contains functions that automate extraction of files, create required jar files, and transform your google-services.json file into a resource required by Android. ACTED can be downloaded from here. For this demo, you will also need the configuration file (firebase-aars.json) from the starter project, to be used by ACTED when extracting the .aar files. If you’ve read the articles at Grijjy, this process may be familiar to you, however ACTED wraps everything up into two easy steps and removes the need for merging .dex files, which is done by Delphi at build time anyway.
3. Download the starter project:
As indicated in the introduction, there is a starter project that is contained in the demos of the Kastri Free library, which you will need to download (use the green “Clone or Download” button) if you wish to use the starter project. The companion jar file (dw-firebase.jar) in the Lib folder contains code for the service portion of the application.
The first thing you should do is modify the package name value in the project options, to match the identifier for your project in Firebase console, e.g:
4. Extracting the resources from the .aar packages:
Note: As per the Grijjy article, you will need to select JDK 1.7 in order for this to work. If you do not have JDK 1.7 installed, you can download it from here.
Once you have the required JDK 1.7, start the ACTED tool, click the Options button, and select the appropriate options, and click OK e.g:
Next, click the “Extract AAR Files” button, click the Load button, navigate to the firebase-aars.json file in the Configuration folder of the Kastri Free library, and click OK. This should load the list box with all required packages, and automatically select which packages that need their res files extracted from them:
Click the ellipsis button for the Extract Path edit, and select a folder for the extracted files. I recommend that you choose a folder which will be common to apps that require Firebase services, however you can choose a subfolder of your project if you desire.
Click the “Extract” button, and ACTED will extract all necessary files, and merge the xml files (where necessary) that contain resources.
5. Creating the jar containing the R classes:
In ACTED, click the “Create R Jar” button, then click the ellipsis button for the Path to libraries and resources edit, and select the folder which you specified in the previous step. Click the ellipsis button for the R Jar Filename edit, and select a location for the jar that will contain the R classes. I recommend using the \lib folder under the folder which is in the “Path to libraries and resources” edit, and to name the jar play-services-r.jar, e.g:
Click the Create R Jar button, and ACTED will use the Java compiler to build the jar.
6. Creating the required strings.xml resource:
If you watched enough of the video of Firebase and Android, you may have noticed that in Android Studio, you can just add the google-services.json file to an Android Studio project, and you’re good to go. With Delphi, the google-services.json file will need to be transformed into strings.xml, which is deployed with the application resources. Start ACTED (if it isn’t running already), and click the “Create strings.xml from google-services.json” button, click the ellipsis button for where the resulting strings.xml will go. Since this is specific to an application, I recommend that this file go somewhere under the project folder. Click the Import button, and ACTED will prompt you for the location of your google-services.json file, e.g:
Click Open, and the strings.xml file will be created with all the required information.
7. Using DeployMan to deploy the resources:
The DeployMan tool from the Grijjy site is a great tool for deploying files in bulk, which is the case for this demonstration. NOTE: Before using this tool, make sure you close the project in Delphi, and make sure you have a backup of your project files.
Close your project in Delphi, download and extract DeployMan, run it, and select the Android tab. Click File, Import .dproj and select your Delphi project. You will need to ensure that both the resources extracted in step 4, and your strings.xml, are included. Click the Add Folder button, select the res folder under the folder of the extracted resources, modify the target directory to be .\res, ensure you have the desired configurations selected (i.e. debug and/or release) and ensure that include subdirectories is checked. Click Add File, select your strings.xml file (generated in the previous step) and modify the target directory to be .\res\values. e.g.:
Click File, Save project
8. Modifying the application manifest:
The AndroidManifest.template.xml file in the project folder will need to be modified in order for Firebase Cloud Messaging to work. The manifest template in the starter project has already been modified, so you may use it as a reference for what changes need to be made. The changes are highlighted with xml comments that contain the text:
**** FCM ****
so that you know where they go. The rest of the manifest is what you would find in a typical manifest for a Delphi application for Android.
9. Managing the .jar files in the project:
The first part of this step is very important, and may affect you if your app relies on any of the Google Play Services that Delphi adds automatically. You must disable all but fmx.dex.jar and dw-firebase.jar in order for Firebase Cloud Messaging to work in your application.
In the Delphi project manager, expand the Target Platforms node, expand the Android node. Right-click each of the jars (except for fmx.dex.jar and dw-firebase.jar) and click Disable:
There are a number of other jar files required for this project, including those that were extracted in step 4. Right-click the Libraries node and click Add. Navigate to the lib folder under the extracted resources folder (from step 2) and select all the jar files, eg:
Click Open. If the jar containing the R classes that was built in step 5 is in a different folder, you will need to follow the same steps to add that, too.
10. Build, run and test the project:
Before running the starter project, you should start the Monitor program that comes with the Android SDK. You’ll find a batch file called monitor.bat in the tools folder of the SDK root. For the default Android SDK install for Tokyo, monitor.bat is located in:
C:\Users\Public\Documents\Embarcadero\Studio\19.0\PlatformSDKs\android-sdk-windows\tools
It is wise to then create a filter, so you see only the messages for your application. To do this, click the green “+” button located in the LogCat tab, in the lower left, enter a name for the filter, and enter the package name for your application in the Application Name box:
Now go back to Delphi, select the debug configuration, compile, and run. Switch to the Monitor application, and watch for the messages when the application runs. The last message you should see is: “Token at startup:” followed by the token. You will need this value to send individual messages to the device, so select the message in Monitor, press Ctrl-C, the message will be copied to the clipboard, and you’ll be able to extract the token from it.
One convenient way of testing Firebase Cloud Messaging is to use the Hurl website. Go to the website, select the POST request type, and in the URL box, paste the following:
https://fcm.googleapis.com/fcm/send
The request will require 4 header values, like pictured here:
The Authorization header requires a name/value pair where the name is: key, and the value is the Server API key, which can be found in your project on Firebase console in the project settings, on the Cloud Messaging tab:
Due to an apparent limitation in Firebase Cloud Messaging, messages must have a “data” section, otherwise Firebase will not process the message on the device when the application is not running (i.e. the associated service for the application receives the message). This is an example message:
[sourcecode language=”javascript”]
{
"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": "2",
"notification_onlyalertonce": "1"
}
}[/sourcecode]
As per the example, in the “to” value, supply the device token that was copied earlier. On the Hurl page, click Add Body, and paste the message into the Parameters box.
Click “Launch Request”, and all things being well you should receive a 200 OK response, and the notification should appear in your app! Next, terminate the app on the device so that you know it is not running, and send another message. Now press the power button on your device so that the display turns off (don’t turn it off completely!), and send another message. You should see the notification appear in the lock screen.
Now for an explanation of the “non-obvious” items in the message:
notification_largeicon can be a url to an image somewhere on the internet. If you use this value, make sure the image is relatively small so that it doesn’t use too much data.
notification_vibrate is either 0 or 1
notification_priority of 1 ensures that the message also appears in the “home” screen.
notification_onlyalertonce is either 0 or 1, and a value of 1 means that the user isn’t repeatedly bothered by the notification
With this implementation, you can include whatever other data you wish as long as it is a valid json pair, and it will be passed to the application if it is already running, or when the user launches it from the notification.
Again, please bear in mind that I am no expert in Firebase Cloud Messaging; Stephane and myself have only just managed to have come this far just recently, and we’re still making refinements to the process. We hope however, that this article can give you a huge “leg up”. Sometime in the next few days, Part 2 will be published, outlining the requirements for making this work on iOS.
Using this now and it works very well! Thank you guys for putting in the work on this one!
Awesome! Thank you!
Great blog post and thanks for the nice words about our blog.
Thanks, Allen!
Great article. I understand you decided not to use fmx and cloud-messaging.dex.jar? What was the reason for this?
I’m using FCM with FMX/cloud-messaging.dex.jar and so far all notifications have been received om my user’s android devices. So what are the drawbacks of this approach?
Can’t wait for the iOS part of your article;) Till now, under iOS 10, I still not know how an FCM notification captured by an active app can be forwarded to the iOS Notification Center. So I hope you have a solution for this in your article on iOS.
The drawbacks of using FCM without the Firebase classes is that we found it very difficult or downright impossible to implement receiving FCM messages properly when the app is not running, because it needs a service for this, and the Notification classes in Delphi cannot be used in a service. Please refer to this report regarding that issue: https://quality.embarcadero.com/browse/RSP-17857
We felt it was a wiser move to create a solution with the newer APIs, since GCM is now deprecated.
If you’re able to see the entire text (title and body) of an FCM message when the app is not running, using only what’s already supplied with Delphi, I’d be interested to hear it. You’ll also find that the default icon is presented with the notification, rather than being able use a custom icon.
Stay tuned because the iOS part is coming soon!
Hi, I use TPushServiceConnection (System.PushNotification) to get device token and receive notifications when app is active. At server side i use FCM http protocol to send notifications (php script). I receive notifications both if app is active and not active. On Android and iOS 10 i receive title and body. On iOS 9 and earlier I only receive body. A smaller version of the app icon is shown in the notification center.
But there is still a lot mystic in my solution, so a fresh and more native implementation as yours is much better. I’m a little bit scared off in installing additional packages and apk’s (never did that before), but i will give it a try;)
Thanhs for the great research and writing it down.
Thank you for super useful post.
When I received message i want to display notification like facebook-message.
I have no idea how to do..
Could yoou give me information about this?
Thanks! What do you mean “like facebook-message”? Can you show me an example?
https://developer.android.com/guide/topics/ui/notifiers/notifications.html?hl=en#Heads-up
I means Heads-up Notifications or pop-up form.
If I received the notification, When the app is not running. I want to display Heads-up Notifications or pop-up form.
Thanks for the additional info. I’ll have to take a look into it, however the notification is posted inside the Java part of the code, and would need to be handled there.
If you could do that, I’d appreciate it.
Just to clarify: are you looking to have actions on the heads-up notification? If so, I’m looking to do something generic, because it would otherwise need a fair amount of work. I would have part of the data message something like this:
“notification_action”: {“title”: “Do something”, “icon”: “somesmallicon”, “id”: “10000”}
And show two actions on the notification: Dismiss, and one using the information specified above. The id could be passed to the application when it opens, so the app knows what action to take
Yes. That’s right.
And I have one more question.
I am tryig to wake phone when received a notification.
Does it need to work inside the Java part of the code?
Thank you.
OK, I’ll be working on being able to use an action when the notification shows. I’ll also look into “waking” the phone.
Brilliant! I have waiting for this information much much time. Thank you.
Only thing: I have one problem with ACTED and step 4 “Click the “Extract” button, and ACTED will extract all necessary files, and merge the xml files (where necessary) that contain resources.”
ACTED extracts and convert libraries to .jar but the resources are not extracted (I have checked the checkboxes as you indicated). I have also tried to extract manually and “merge” xml, but I don’t get to do it. Could you help me, please?
Thanks in advance.
When you do the extract process with ACTED, it extracts everything to the “Extract Path”, and creates two subfolders, lib and res. The .jar files are extracted to the lib folder, and all the resources are extracted and merged to the res folder. Please make sure that the “Selected AAR Files” list looks *exactly* as it does in the article, i.e. the same number of files, and the first two items have their checkboxes checked.
Hello. Under Windows 7 ACTED doesn’t work fine, but under Windows 10 no problem. I have tested with update files and work perfectly. Thank so much. Great great great job!
Hello, I’ve tried it and works great, but when application is closed, nothing happens when I click in the notification. It should start?
Some additional code is needed to start an activity?
Thank you very much
My apologies: some refactoring I did in between publishing the article and now, broke it. I’ve now fixed it – the affected files are:
https://github.com/DelphiWorlds/KastriFree/blob/master/Features/Firebase/DW.Firebase.Messaging.Android.pas
https://github.com/DelphiWorlds/KastriFree/blob/master/Lib/dw-firebase.jar
Hello, I’ve updated that files and I’ve done a new build, but I see no difference. My application don’t start.
Thanks in advance
Have you done a Clean, then Build?
With a previous clean and then a build works great!
Thanks!
What’s the actual problem with it on Windows 7?
Hello
I didn’t get to extract the resources. ACTED extracts the first jar file but when it has to extract the resources of the first jar file, it doesn’t do anything. I was waiting much time but no extraction. Could you check it in your system under Windows 7 or virtual machine of Windows 7?
So, I tested under Windows 10 and it works. I have other computer with Windows 10.
Thank you.
Just finished implementing Google Signin for social login in Delphi for iOS, and now getting started on doing the same for Android. Going to try and use your helper tool ACTED.
Excellent! I’d be interested to hear how it goes
I am still going through the process of creating the Delphi Google Signin for Android and I managed to get ACTED to extract the jars, build the R classes Jar and create the strings.xml. Congratulations on figuring these steps out and improving the process on creating the R.java. It never occurred to us at Grijjy that you could simply make this as another JAR and use it directly. However, I did run unto 4 bugs in the ACTED tool. Should I report those here, or would you rather I send the list of them to you directly?
You could either report them in the associated Github project:
https://github.com/DelphiWorlds/Tools/issues
or email them to me directly. I’m considering making the source public at some point.
Hi
I am trying to follow it .
I did all steps.. but when I run the project, it gives me an error message “Java class JDWFirebaseMessagingService could not be found”.
Thank you.
Please re-check step 9, particularly that you have dw-firebase.jar added to your project.
I added dw-firebase.jar to my project.
When Form created, the part of creating FirebaseInstanceId is fine.. but, only the part of creating FirebaseMessaging gets error message..
procedure TForm1.FormCreate(Sender: TObject);
begin
inherited;
FInstanceId := TFirebaseInstanceId.Create;
FInstanceId.OnTokenRefresh := InstanceIdTokenRefreshHandler;
FMessaging := TFirebaseMessaging.Create;
FMessaging.OnMessageReceived := MessagingMessageReceivedHandler;
// The first time the app is run, token will be blank at this point, however the OnTokenRefreshHandler will be called
mmoTokenMemo.Lines.Text := FInstanceId.Token;
TOSLog.d(‘Token at startup: %s’, [mmoTokenMemo.Lines.Text]);
FMessaging.Connect;
end;
If you’re still receiving the same error, it means dw-firebase.jar is not being included when the application is compiled. Please check your Project Deployment. In the IDE, click Project|Deployment, then click the Local Name heading and make sure there is only one classes.dex entry. For the starter project, the Local Path for that entry should be Android\Debug
Hello again.
Can i Modify dw-firebase.jar?
Because I want to put ‘Power Manager’ source for ‘Wake up’.
I’ll publish the source for it sometime soon. In the meantime, there’s a number of decompilers that you could use to extract the source for the .jar, including JADX: https://github.com/skylot/jadx
Once you have the source. if you’re able to code in Java, you’ll be able to make whatever changes you need.
Thank you for kindly explanation.
Now It worked!!
Thank you so much!
Hello, Dave! When you say that default google services are disabled, do you mean like InAppPurchase? If so, is there a work around for it? Thank you 🙂
It’s possible that the billing jar may not need to be disabled. I’ve only gone on the advice from Stephane (who is mentioned in the article), and since FCM works with it disabled, I haven’t looked any deeper.
You could re-enable it yourself and see if FCM still works, and then see if InAppPurchase calls work. I will look at it tonight.
I will be taking a much deeper look into it soon, as I plan to implement other Google Play Services so that people who want to use FCM don’t miss out on the other services. This is planned to be part of a commercial package, and will include Firebase Database
I’ve just checked, and it’s possible have google-play-billing.dex.jar and google-play-licensing.dex.jar enabled (and the demo still works), so they should still work, however please note that I have not tested either as yet. As per my other reply, I’m working towards having a complete package to make sure everything is available.
Hello. I added new Java file in dw-firebase.jar. And I modifyed ‘DW.Androidapi.JNI.FirebaseServiceHelpers.pas’ for adding new class on new Java file, then I got ‘Invoke error: method not found.’ error message. However when I added new method in to DWNotificationPublisher java file, it worked!.
If I remake jar file adding new java file, should I need to do something?
Thank you.
In Delphi, make sure you “Clean” your project before running it otherwise Delphi won’t pick up the parameter list changes for the import from the jar.
Yes, I did clean and rebuild before run.
Thank you.
Aslam-o-alikum can any one help me that how to do Push Notifications using Firebase Cloud Messaging FCM & SQL server in android app
Hello
I didn’t get to extract the resources. ACTED extracts the first jar file but when it has to extract the resources of the first jar file, it doesn’t do anything. I was waiting much time but no extraction. Could you check it in your system under Windows 7 or virtual machine of Windows 7?
Sorry, I don’t have Windows 7. Perhaps someone else with it could check?
I’ve now added a zip file:
https://github.com/DelphiWorlds/KastriFree/blob/master/ThirdParty/Firebase.zip
Which contains the extracted jar and res files, and a pre-built R jar file. These are for Firebase and Google Play Services 10.2.1, as per the article, so steps 4 and 5 are no longer necessary
I have a problem, received data is ‘gcm.sent_time=1508403560168’#012’gcm.from=6592041988’#012’gcm.message_id=0:15084035604053%ffdeee4fffdeee4f’#012’gcm.ttl=0’#012
for me,
where is the message body?
Hi Dave! Thanks and respect for that great tutorial!
It builds finebut unfortunately I am Stuck with this error wheren deploying. I buildt the R file on my own and also used the one you supplied that doesn’t make a difference.
Fehler: E2312 D:\_work\_testing\_bin\Android\FCMStarter\AndroidManifest.xml:42: error: Error: No resource found that matches the given name (at ‘value’ with value ‘@integer/google_play_services_version’).
Would you mind helping me here?
Thanks!
Michael
That error message is likely as a result of improperly performing step 7 of the article. You can check that it has been done properly by clicking on Project|Deployment, selecting Android platform, and clicking the “Remote Path” column so that they’re sorted. There should be quite a number of entries that have a Remote Path that starts with .\res.
Thanks a lot! It helps, if you can read, I did not modify the target paths. Now the app can be deployed but crashes on receiving a message – I am sure I made an other mistake and check all steps thoroughly before bothering you again.
Michael
Hello Dave,
sorry to bug again but I am stuck now with the app crashing when receiving a message. I am not able to debug as it doesn’t reach even TFirebaseMessagingReceiverListener.onReceive.
Here is my environment:
– Delphi Tokyo enterprise latest updates and patches applied
– SDK up to date (25.2.5), all required components installed, API 22 (also tried with API 23)
– Targets: Nexus 5 with Android 6.0 and Aquarius BQ 5 X
– JDK 1.8.0_144 (used 1.7 for creating the libs then uninstalled and went back to 1.8 as I need it in an other project)
– Used Firebase Console for sending messages and also the way with hurl.it directly adressing the device
I have no Idea where I could now check, any help is very appreciated! Thanks!
Michael
Update:
I used adb logcat and discovered that error:
10-20 18:24:58.711 32092 32092 E AndroidRuntime: java.lang.RuntimeException: Unable to instantiate receiver com.embarcadero.gcm.notifications.GCMNotification: java.lang.ClassNotFoundException: Didn’t find class “com.embarcadero.gcm.notifications.GCMNotification” on path: DexPathList[[zip file “/data/app/de.itcms.homeauto-1/base.apk”],nativeLibraryDirectories=[/data/app/de.itcms.homeauto-1/lib/arm, /data/app/de.itcms.homeauto-1/base.apk!/lib/armeabi-v7a, /vendor/lib, /system/lib]]
After re-enabling cloud-messaging.dex.jar everything works fine.
I also rebooted the phone to make sure that the background service really receives messages and – it does.
Do I have to expect any problems?
Thanks,
Michael
In the Project Options for Android, in the “Entitlement List” section, the “Receive push notifications” option should be unchecked, as this project does not use the one supplied with Delphi. If you have it checked, that might explain the error, otherwise it’s very odd for that to happen.
Thanks again, I had that checked, now it works perfectly fine!
Hello Dave.
How can I know between running an icon by pressing it and running it by pressing an alert of the top?
What do you mean by “running an icon”? Do you mean starting the app by tapping the icon? Being able to tell the difference between the two would probably need some changes in the code.
Sorry for bad explanation.
I want to show the notification history form when I tap notification alert at the top.
Is there any method or property that tell you how to run the app?
hi
i try to follow all step and after run the app, no error but no token received. how solve this ? . Entitlement List is checked. manifest exactly same.
please advise
thanks
Does this run on Delphi 10.2.2 ???? I tried but i get an exception at ‘TokenMemo.Lines.Text := FInstanceId.Token;”
What is the exception? Please provide a call stack if you can
it ist a EJNIException ‘java.lang.IllegalStateException : Default FirebaseApp is not initialized in this process com.mycomp.FCMStarter. Make sure to call FirebaseApp.initializeApp(Context) first.’
How can i provide the call stack? i see it when debugging
Please double-check that the required jar files are added as per step 9
Thanx a lot ….. i used the Firebase.zip from thirdparty as recomended earlier … now the exception is gone ….. i will test further!
Dear Dave!
Thanks again for your immediate Help!
I have a generell question : i would like to extend your api to send upstream messages from the client!
As far as i figured out i have to extend the JNI File for Firebase
[JavaSignature(‘com/google/firebase/messaging/FirebaseMessaging’)]
JFirebaseMessaging = interface(JObject)
[‘{F33877E5-DAA2-4097-9527-CE1CDBD66A67}’]
procedure subscribeToTopic(topic: JString); cdecl;
procedure unsubscribeFromTopic(topic: JString); cdecl;
procedure send(message: ?????);
end;
The Firebase Reference says that there is a RemoteMessage Java Object to build this message?
Since i am new to JNI i dont now how to go on.
My idea is to get this java class inside the jni wrapper … But how to get the [‘{CAB4B525-5E1E-40E8-9A7C-CA3608FE26C6}’] for this class.
I’ve updated the relevant file:
https://github.com/DelphiWorlds/KastriFree/blob/master/API/DW.Androidapi.JNI.Firebase.pas
To add the send method, and the related classes, however I am yet to test it, so no guarantees.
Perfect! I had not time yet to try! Monday …..
Is there any good documentation about the JNI Interface ???????
Tried the whole day, but had no luck!
I dont know how to work with the JNI and there is no help in Delphi for this issue!
How do i cast a JRemoteMessage to TJRemoteMessage ????
You don’t cast a JRemoteMessage to a TJRemoteMessage. As per the documentation:
https://firebase.google.com/docs/cloud-messaging/android/upstream
You use an instance of Builder from RemoteMessage (the Delphi equivalent is JRemoteMessage_Builder). It would go something like this (untested):
One problem: RemoteMessage.Builder and RemoteMessage.Notification didn’t import properly (Java2OP sometimes confuses class methods with instance methods), so I’ve fixed that, and updated:
https://github.com/DelphiWorlds/KastriFree/blob/master/API/DW.Androidapi.JNI.Firebase.pas
You’ll need to update that, otherwise the code above won’t even compile.
Dear Dave, thank you so much …. i will try today ….. well if you would like i can test your changes to the Firebase Implementation!
I haven’t changed anything other than the file I mentioned, however you’re welcome to test that. I’m considering implementing a Send method on TFirebaseMessaging once I have the iOS side sorted out, though
Dear Dave! I have received my First Upstream Message on Android ……. The JNI Wrapper you modified is working! Thank you so much!
By the way : is there a good implementation for XMPP Protocol for Delphi. I wrote a rudimentary implementation for this!
Thanx in advance!
Awesome! There’s one XMPP implementation here (based on Synapse, I think): https://github.com/oulan/XMPP-Delphi
Hmmm …. well ….. i am not familiar with synapse ……… meanwhile i wrote my own small implementation for this. I just need a few messages, not the whole implementation.
One Thing that is maybe important for authentification :
i need to send this stanza to the sever! Google documentation says the following about authentification
The XMPP server must respond using the PLAIN auth method, providing the server key from the Cloud Messaging tab of the Firebase console Settings pane.
MTI2MjAwMzQ3OTMzQHByb2plY3RzLmdjbS5hb
mFTeUIzcmNaTmtmbnFLZEZiOW1oekNCaVlwT1JEQTJKV1d0dw==
This information is not correct!
The Token in there is Base64 encoded and does contain the key also the user login
Base64 := TNetEncoding.Base64.Encode(#0 + ‘xxxxxxxxxxxx@gcm.googleapis.com’ + #0 + ‘API-KEY’);
It took me a long time to figure out, how this really works!
Hi Franz,
I’d be happy to help out with your XMPP enquiry, however can we continue the discussion elsewhere?
If you’re OK with using Slack (a chat/collaboration tool), you could join my Slack team by going to:
http://slack.freedelphicode.com
Or send me a message by using the contact form:
http://blog.delphiworlds.com/#contact
Perfect Dave! i will later implement a XMPP Sever or using a Firebase Realtime DB for testing. Until now … on android i do not get any error when i call the send method!
Best wishes from that country that sounds similar to Australia! When i introduce myself, i am always asked, …. ” oh, the country with the kangaroos! But there are no Kangaroos available in Austria! 😉
Implemented your solution and it works great. Thank you for this.
I have one challenge however: When the app is not running and a notification arrives, and I tap on the notification in the system tray, it opens the app alright, but I cannot figure out a way to get the startup notification.
Hi Dave! Are there any solutions to the notification problem in Android 8 SDK 26? Thank you!
Hi Fernando,
Interesting that you should ask that 🙂 I’m working on an updated solution that should bring everything up-to-date, including using the latest Firebase SDK (both Android and iOS), and support for Android API 26+, and iOS 10+
I plan to have it completed in the next couple of days
What a wonderful new. Many thanks Dave!
[…] Fernando Leal on Adding Firebase Cloud Messaging to your mobile apps – part 1 […]
Hi Dave!
When I compile and run the FCMRevisited project, all works perfectly. When I start from a new project by following all the steps the project compiles but I have an error at launch:
09-05 08:55:02.321: W/System.err(8029): java.lang.IllegalStateException: Default FirebaseApp is not initialized in this process com.agisoft.AGIPrevision. Make sure to call FirebaseApp.initializeApp(Context) first.
I replaced the .jar with those of Firebase.zib, I get the same result. I replaced them with those of the FCMRevisited project, same result.
My version of Delphi is Tokio 10.2.3
I have no idea, can you help me please?
Did you include the changes to AndroidManifest.template.xml? i.e. the parts that start like this:
**** FCM **** Services BEGIN
Hi, thank you for your post!
An elaborated set of instructions and, as someone else said, some bit of uncomfortable blackboxes in my app (I know I can still decompile and verity the code), but I confirm your solution is working for Android. I will go test it for iOS too, in the next hour.
However, I noticed a bug. If the app is running in background, and a push notification is received, if you tap on the notification in NC, the actual notification does not get fired in the app.
Any idea what am I doing wrong? If I can figure this out, I will use your solution instead of Delphi’s.
As you probably know, 10.2.3 has a patch with the missing gcm service which kind of works, but still has something I do not like, as the notification does not get displayed well when app is not running.
So please help me out, tell me what am I doing wrong, maybe there is another interface I need to implement or something so I can receive notifications in app, after tapping them in Notification Center.
Cheers and thanks again!
Mihai
Hi again,
Found the expected fix in “revisited” section: line 138 containing IsForeground should be commented out in
master/Features/Firebase/DW.Firebase.Messaging.Android.pas
Did that. I got an empty notification every time the app starts, corresponding to the one related to port. I can strip it off, once I know what is all about.
However this did not fix the issue with firing notifications when the app is in background, after tapping the notification in NC.
Little help, please?
Cheers!
Mihai
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.