Firebase Cloud Messaging with Delphi 10.1 Berlin update 2.
A comprehensive step by step guide, covering everything you need to know to receive push notifications to your Android device using Firebase Cloud Messaging and the latest Delphi 10.1 Berlin update 2.
Push notifications let your application notify a user of new messages or events even when the user is not actively using the application (downstream messaging) (Parse.com). On Android devices, when a device receives a push notification, the application's icon and a message appear in the status bar. When the user taps the notification, they are sent to the application. Notifications can be broadcast to all users, such as for a marketing campaign, or sent to just a subset of users, to give personalised information. To provide this functionality I will rely on Firebase Cloud Messaging which is the new version of GCM (Google cloud messaging) and Delphi to develop the Android application.
Create your Firebase project by visiting the console if you still don't have one and in this project create an Android App.
I already have one project so I will use this one for my demo. Once in the project, go to Overview -> Add another app -> Android:
And give it a sensible name. In my case I called the package com.embarcadero.FirebaseCloudMessaging. This package name is important as it will be referenced later on. Once you click Add App, you will receive a google-services.json file which contain information that we will use later.
The package name is defined in your Delphi project:
So make sure that everything matches with the name you give to your Firebase application as the manifest file will contain this information.
Now that we have our project configured, we need to request Firebase a unique token for our Android device. You can see the description here as to how to get the FCM token via Android Studio, but I will show the necessary steps to get the same value from our Delphi application.
Basically we are trying to get the same value from FirebaseInstanceId.getInstance().getToken(). We will achieve the same behaviour by using TPushServiceManager which is the unit responsible for handling push notifications.
The following code snippet tries to request the FCM token via TPushServiceManager:
Now, to allow this code to work correctly, we will have to configure few things.
a) Enter the Sender Id.
In the source code snippet above, I'm mentioning the SENDER ID. This sender id, can be found under Firebase -> Project Settings -> Cloud Messaging:
This is the value you have to put here:
PushService.AppProps[TPushService.TAppPropNames.GCMAppID] := 'SENDER ID';
Knowing that the GCMAppId is actually the Sender Id has been a quite a struggle for some users and you can see my answer on Stack overflow.
b) Configure the project to receive push notifications.
In the Delphi IDE, go to your project options -> Entitlement List and set the property Receive push notifications to true.
c) Configure the AndroidManifest.template.xml file.
Before we try to run the code above, we'll have to configure the manifest file to grant our device permissions to connect to Firebase. If you don't configure the permissions, you might run into an exception like the one below:
Error message: EJNIException with message 'java.lang.SecurityException: Not allowed to start service Intent { act=com.google.android.c2dm.intent.REGISTER pkg=com.google.android.gms (has extras) } without permission com.google.android.c2dm.permission.RECEIVE'.
See the code snipped below for reference:
The full source code of the solution can be found here for reference where you can find the manifest files.
Once everything is configured, we can now test if we can receive the FCM token. Here is a screenshot of my project so you can see that there are two buttons, one to receive the token and the other one to store this token somewhere so the system that sends the notification knows the receiver.
Let's see the project in action here:
As you can see in the image above, I get the DeviceID and the FCM Token. The one we are interested in is the FCM Token. This token is quite large so it does not appear completely on the screen.
Now we need to configure what to do when we receive a notification and how this notification is built.
The following code snipped will configure the OnReceiveNotification event and will display a notification using the TNotificationCenter class.
Notice that the ServiceNotification variable contains a DataKey member which contains a JSON envelope. This object will contain all the information of our push notification. Here you can see how this notification looks like:
Notice that the message is part of the gcm.notification.body property and this one is the one that we will use for our DataObject.GetValue method.
Let's see the application in action:
Here you can see side by side my Android device and Firebase Notification testing system. Once the application is ready to receive notifications, you just need to send the notification using the configured app or the token if you want to target a single device.
Next step is to store these tokens on the cloud and use your own system to deliver those messages.
Please, do not hesitate to contact me if you have any further questions.
Related links:
Push notifications let your application notify a user of new messages or events even when the user is not actively using the application (downstream messaging) (Parse.com). On Android devices, when a device receives a push notification, the application's icon and a message appear in the status bar. When the user taps the notification, they are sent to the application. Notifications can be broadcast to all users, such as for a marketing campaign, or sent to just a subset of users, to give personalised information. To provide this functionality I will rely on Firebase Cloud Messaging which is the new version of GCM (Google cloud messaging) and Delphi to develop the Android application.
1. Create your Firebase project
Create your Firebase project by visiting the console if you still don't have one and in this project create an Android App.
I already have one project so I will use this one for my demo. Once in the project, go to Overview -> Add another app -> Android:
And give it a sensible name. In my case I called the package com.embarcadero.FirebaseCloudMessaging. This package name is important as it will be referenced later on. Once you click Add App, you will receive a google-services.json file which contain information that we will use later.
The package name is defined in your Delphi project:
So make sure that everything matches with the name you give to your Firebase application as the manifest file will contain this information.
2 Request your FCM Token
Now that we have our project configured, we need to request Firebase a unique token for our Android device. You can see the description here as to how to get the FCM token via Android Studio, but I will show the necessary steps to get the same value from our Delphi application.
Basically we are trying to get the same value from FirebaseInstanceId.getInstance().getToken(). We will achieve the same behaviour by using TPushServiceManager which is the unit responsible for handling push notifications.
The following code snippet tries to request the FCM token via TPushServiceManager:
Now, to allow this code to work correctly, we will have to configure few things.
a) Enter the Sender Id.
In the source code snippet above, I'm mentioning the SENDER ID. This sender id, can be found under Firebase -> Project Settings -> Cloud Messaging:
This is the value you have to put here:
PushService.AppProps[TPushService.TAppPropNames.GCMAppID] := 'SENDER ID';
Knowing that the GCMAppId is actually the Sender Id has been a quite a struggle for some users and you can see my answer on Stack overflow.
b) Configure the project to receive push notifications.
In the Delphi IDE, go to your project options -> Entitlement List and set the property Receive push notifications to true.
c) Configure the AndroidManifest.template.xml file.
Before we try to run the code above, we'll have to configure the manifest file to grant our device permissions to connect to Firebase. If you don't configure the permissions, you might run into an exception like the one below:
Error message: EJNIException with message 'java.lang.SecurityException: Not allowed to start service Intent { act=com.google.android.c2dm.intent.REGISTER pkg=com.google.android.gms (has extras) } without permission com.google.android.c2dm.permission.RECEIVE'.
See the code snipped below for reference:
The full source code of the solution can be found here for reference where you can find the manifest files.
Once everything is configured, we can now test if we can receive the FCM token. Here is a screenshot of my project so you can see that there are two buttons, one to receive the token and the other one to store this token somewhere so the system that sends the notification knows the receiver.
Let's see the project in action here:
As you can see in the image above, I get the DeviceID and the FCM Token. The one we are interested in is the FCM Token. This token is quite large so it does not appear completely on the screen.
Now we need to configure what to do when we receive a notification and how this notification is built.
3 Receive your first FCM Push notification
The following code snipped will configure the OnReceiveNotification event and will display a notification using the TNotificationCenter class.
Notice that the ServiceNotification variable contains a DataKey member which contains a JSON envelope. This object will contain all the information of our push notification. Here you can see how this notification looks like:
Notice that the message is part of the gcm.notification.body property and this one is the one that we will use for our DataObject.GetValue method.
Let's see the application in action:
Here you can see side by side my Android device and Firebase Notification testing system. Once the application is ready to receive notifications, you just need to send the notification using the configured app or the token if you want to target a single device.
Next step is to store these tokens on the cloud and use your own system to deliver those messages.
Please, do not hesitate to contact me if you have any further questions.
Related links:
- GCM in Delphi Seattle without BAAS.
- Issue with GCM Push notifications service Delphi XE6.
- SecurityException: not allowed to start service intent.
- Send a notification to an android device.
- RAD in Action: Build connected multi-device apps using BaaS.
- GCM framework tutorial.
- User Token to subscribe topics in Firebase.
- Using FCM token obtained via batchimport (iOS).
- Authorization part of http post request FCM.
Jordi
Embarcadero MVP.
Hello,
ReplyDeleteGreat article! .. I am using a third party library to manage the push notification.
This is a good way to implement own system push ...
Have you a example in order to use a push Apple server ?
thanks
regards
Antonello
Hi Antonello,
DeleteUnfortunately I don't have any example using iOS. Probably it's similar but you'll have to check what are the parameters required in TPushServiceManager.
Regards,
Jordi
Any chance of ever making an iOS guide?
DeleteThis Android write up worked very well for me it seems. I have to write the Android Service, but other than that it was great.
For iOS I am just hitting road blocks that I can't find answers to.
I can't even get the Device Token ....
It would be great if you have time to do an iOS flavor of this write up for us that are struggling.
Hold-your-hand instructions and with pictures, on these kind of topics is great.
Thanks for good write up!
Hi Steven,
DeleteI don't think I will do one for iOS as it requires additional effort and time that I don't have. I know it's different for iOS and you have to change the code in the GetServiceByName to use this instead:
PushService := TPushServiceManager.Instance.GetServiceByName(TPushService.TServiceNames.APS);
This will make it work for iOS. Also bear in mind that the process is a bit different and you need to send a different request first to get the token. Also the device needs to be registered.
I hope this helped.
Cheers,
Jordi
Congratulations
ReplyDeletethanks!
DeleteHola Jordi. Te felicito por el artículo. Me ha servido mucho de ayuda. Quisiera saber como se pueden recibir notificaciones, cuando la aplicación está cerrada, es decir, no cargada en la memoria. He probado tanto cuando la aplicación está en el background como en el foreground y funciona. El problema es cuando fuerzas el cierre de la aplicación. En ese momento, ya no se reciben notificaciones. Gracias por adelantado.
ReplyDeleteThanx very much
ReplyDeleteWhat version of Android do you have on your device? The device id comes up blank on my Android 7.1.1. I note that the code in FMX.jar uses:
ReplyDeleteSecure.getString(getContentResolver(), "android_id")
Which it then "dehashes" to a string. It may be that this value is blank on newer versions of Android (or at least on my Nexus 5X)
Hi David,
DeleteI'm using Android 6 Marshmallow and I had similar issues when moving away from previous versions of Android as there is always something different that needs modifying. You'll have to fiddle a bit as to see what's different.
Cheers,
Jordi
В окне уведомления нет заголовка и текста (только иконка приложения). Отправляю например через Firebase Console
ReplyDeletedmokrushin@fortebank.com
HI Dmitriy,
DeleteYou'll have to check the notification component as to see what can be done with it. Bear in mind that the notification component calls the underlying Android component so I don't know what you will be allowed to do with it.
Cheers,
Jordi
Good article, works fne, just when I close the app (yours or mine), there is a segmentation fault : https://puu.sh/tT6Le/9cf4d2f07e.png
ReplyDeleteHi Helge,
DeleteI didn't notice it. I'll have to test it again as to see where the error happens.
Regards,
Jordi
Also you wrote about that file google-services.json which "we will use later"... But i can't find it anywhere mentioned again ... Does that mean it isn't used or in a later article that's yet to be published ?
ReplyDeleteGreetings
Hi Helge,
DeleteYes I thought about that. The file will be used later on when I start saving tokens.
Cheers,
Jordi
but how to handle google-services.json with delphi? because it's look like it's must be processed by The google-services plugin ( https://firebase.google.com/docs/reference/gradle/ )
DeleteHi! Nice and useful article. Actually I have tried to send message FCM using topic. On the FCM user manual, it recommend to use that like "FirebaseMessaging.getInstance().subscribeToTopic("news")". Do you know how to build this issue? It it very difficult to build without not much information with DELPHI than JAVA.
ReplyDeleteHi,
DeleteFor that I guess that you'll have to do some manual filtering through the API. You'll have to look for it on that end.
Cheers,
JOrdi
Hi! Grate article. I have a question. Is it possible to use topic for messaging to all users?
ReplyDeleteHi there,
DeleteYou have to build your own topic platform. When a user is granted then you store his token somewhere and add a specific topic. Then when you push the notification you only push specific notifications according to the topic.
Cheers,
Jordi
Dear Jordi,
ReplyDeleteWhen trying to make a request "post" via Delphi Seattle up2 or the RESTDebugger to Firebase with HTTP, returns the error:
"HTTP / 1.1 401 The request was missing an Authentification Key (FCM Token). Please, refer to section" Authentification "of the FCM documentation, at https // = firebase.google.com/docs"
Http://www.netnucleo.com.br/imagens/delphi_http/rest_debugger_01.jpg
Http://www.netnucleo.com.br/imagens/delphi_http/rest_debugger_02.jpg
Using the Chrome Postman extension, it works.
http://www.netnucleo.com.br/imagens/delphi_http/postman_01.jpg
http://www.netnucleo.com.br/imagens/delphi_http/delphi_01.jpg
See the Delphi code:
Try
IdIOHandler: = TIdSSLIOHandlerSocketOpenSSL.Create (nil);
IdIOHandler.ReadTimeout: = IdTimeoutInfinite;
IdIOHandler.ConnectTimeout: = IdTimeoutInfinite;
IdHTTP: = TIdHTTP.Create (nil);
Try
IdHttp.Request.Clear;
IdHttp.Request.CustomHeaders.Clear;
IdHttp.Request.ContentType: = 'application / json';
Idhttp.Request.Charset: = 'UTF-8';
IdHTTP.IOHandler: = IdIOHandler;
IdHTTP.ReadTimeout: = IdTimeoutInfinite;
IdHTTP.Request.Connection: = 'Keep-Alive';
IdIOHandler.SSLOptions.Method: = sslvSSLv23;
IdHTTP.Request.Method: = 'POST';
IdHTTP.Request.CustomHeaders.Values ['Authorization: key']: = 'AAAAYsnMbsY: APA91bEjYZK-xxxxxxx ......';
idHttp.Request.CustomHeaders.Values [ 'Content-Type'] = 'application / json';
JsonString: = '{"to": "APA91bFJSdGW_yrX7p_TNKZ4k0OpdXTQM6xdd7BUsslk6zSvZlBmoAnfvyX-nBm4DYY-xxxxx ......",' + '
'' Data ": {'+
'"Nick": "Push Test",' + '
'"Body": "Push body",' +
'Room': 'Just one test' '+
'},}';
JsonToSend: = TStringStream.Create (jsonString);
Try
Response: IdHTTP.Post = ( 'https://fcm.googleapis.com/fcm/send' JsonToSend);
Response: = response.Replace (Char (# 10), '');
Except
On E: EIdHTTPProtocolException
Memo1.Lines.Insert (0, e.ErrorMessage);
End;
Memo1.Lines.Insert (0, response);
Finally
IdHTTP.Free;
End;
Finally
IdIOHandler.Free;
End;
Hi there,
DeleteI think your request is malformed. Are you using your server key as authentication key? And your json string should contain the "data" node. Check out the documentation here:
https://firebase.google.com/docs/cloud-messaging/server
Cheers,
Jordi
Hi Jordi,
DeleteI am using the key as image:
http://www.netnucleo.com.br/imagens/delphi_http/key_server_01.jpg
My JSON String Contains o node "data":
jsonString := '{"registration_ids" :["APA91bFJSdGW_yrX7p_TNKZ4k0OpdXTQM6xdd7BUsslk6zSvZlBmoAnfvyX-nBm4DYY-.....xxxxx"]}' +
'{"data" : { ' +
'"Nick" : "Teste de Push", ' +
'"body" : "Corpo do push", ' +
'"Room" : "Apenas um teste" ' +
'},}';
Sorted out. See this link: http://stackoverflow.com/questions/42392627/delphi-google-firebase-http
ReplyDeleteEven so, thank you very much for your support.
great!
DeleteGreat Jordi !!
ReplyDeleteBut When my app is closed, the notification received does not show the message, only an alert with the icon and package name appears on my device notification (if the app is closed). Can you help me ?
Jordi Grifoll.
Hi Jordi,
DeleteYou might have to build a background service for that so it's alive and can accept requests. Or keep the application alive on background also but the first approach is better.
http://docwiki.embarcadero.com/RADStudio/Seattle/en/Creating_Android_Services
Cheers,
Jordi
Great Jordi !!
ReplyDeleteBut When my app is closed, the notification received does not show the message, only an alert with the icon and package name appears on my device notification (if the app is closed). Can you help me ?
Jordi Grifoll.
Hi Jordi, Thank you for the article and sorry for my English.
ReplyDeleteWell, i'm trying to POST to this url "https://iid.googleapis.com/iid/info/APA91bFICaJ9rbQccb....B1G0SMK7GA8bjeG1vP391e5hp_XNRqRHWWO8SSL93h-E1Fv_CJeaQki3RZ....cm0A25EuVvax9J3k5nQCQl6ltkw" with the FCM Token, but the response i get is "{"error":"InvalidTokenVersion"}".
Firebase's documentation references another FCM token format.
Do you know why this is happening?
Hi Jordi, Thank you for the article and sorry for my English.
ReplyDeleteWell, i'm trying to POST to this url "https://iid.googleapis.com/iid/info/APA91bFICaJ9rbQccb....B1G0SMK7GA8bjeG1vP391e5hp_XNRqRHWWO8SSL93h-E1Fv_CJeaQki3RZ....cm0A25EuVvax9J3k5nQCQl6ltkw" with the FCM Token, but the response i get is "{"error":"InvalidTokenVersion"}".
Firebase's documentation references another FCM token format.
Do you know why this is happening?
Hi Jordi, Thank you for the article and sorry for my English.
ReplyDeleteWell, i'm trying to POST to this url "https://iid.googleapis.com/iid/info/APA91bFICaJ9rbQccb....B1G0SMK7GA8bjeG1vP391e5hp_XNRqRHWWO8SSL93h-E1Fv_CJeaQki3RZ....cm0A25EuVvax9J3k5nQCQl6ltkw" with the FCM Token, but the response i get is "{"error":"InvalidTokenVersion"}".
Firebase's documentation references another FCM token format.
Do you know why this is happening?
Hi Alberto,
DeleteAre you using the parameters mentioned in the help about authentication and details? https://developers.google.com/instance-id/reference/server
Just make sure that your post includes those headers.
Cheers,
Jordi
Hi Jordi,
DeleteI tried to extend your solution so I can obtain app info from firebase but I am getting a http/1.1 400 bad request
Here is part of my code (Using Berlin 10.1 upd2)
const
cFCMAPIServerKey = 'AAAAHGT3GQY:APA91b.....';
procedure TMainForm.GetDeviceInfoFromToken;
var
Response: string;
begin
Response := TFirebaseRest.New.GetDeviceInfo(DeviceToken, cFCMAPIServerKey);
MemoStatus.Lines.Add(Response);
end;
function TFirebaseRest.GetDeviceInfo(const Token, APIKey: string; Detailed: Boolean = True): string;
var
IdHTTP: TIdHTTP;
IdIOHandler: TIdSSLIOHandlerSocketOpenSSL;
Response: string;
Details: string;
begin // https://iid.googleapis.com/iid/info/[?details=true|false]
IdIOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(Nil);
try
IdIOHandler.ReadTimeout := IdTimeoutInfinite;
IdIOHandler.ConnectTimeout := IdTimeoutInfinite;
IdIOHandler.SSLOptions.Method := sslvSSLv23; //~
IdHTTP := TIdHTTP.Create(Nil);
try
// IdHTTP.ReadTimeout := 30000;
// IdHTTP.HandleRedirects := True;
IdHTTP.IOHandler := IdIOHandler;
IdHTTP.ReadTimeout := IdTimeoutInfinite;
IdHTTP.Request.Connection := 'Keep-Alive';
IdHTTP.Request.Charset := 'utf-8'; //+
IdHTTP.Request.ContentType := 'application/json';
IdHTTP.Request.CustomHeaders.Add(Format('Authorization: key=%s', [APIKey]));
if Detailed then
begin
Details := '?details=true';
end;
Response := IdHTTP.Get('https://iid.googleapis.com/iid/info/' + Token + Details);
Response := Response.Replace(Char(#10), '');
Result := Response;
finally
IdHTTP.Free;
end;
finally
IdIOHandler.Free;
end;
end;
These two endpoints which I have implemented in different methods also fail
https://iid.googleapis.com/iid/v1:batchAdd
https://iid.googleapis.com/iid/v1/IID_TOKEN/rel/topics/TOPIC_NAME
Could you point out where I am messing up?
ReplyDeleteIf the application is closed, the notification arrives normally, but the message appears without text, with only the name of the application.
Would you help me?
Hi Lunar Tecnologi,
Deleteyou'll have to research a bit about the notification component. I experienced this issue too but I didn't delve into it any further. You might want to consider using a service instead that can be up all the time and receiving those requests.
Cheers,
Jordi
some cell phones as xiaomy close the app after 5 minutes... including the background service
DeleteHi Jordi,
ReplyDeleteThanks for providing such useful code and article.
I am using 10.2 Tokyo and have a problem registering - either your code untouched or my own app.
When setting ServiceConnection.Active := True;
I get the following exception.
"Exception class EJNIException with message 'java.io.IOException: MAIN_THREAD'."
I can trace it down to the line
"LToken := LGCM.Register(LSenderIds);" in TGCMPushService.Register
I believe that is a call into the Java com/google/android/gms/gcm/GoogleCloudMessaging.register (in Android.JNI.PlayServices).
Any thoughts on where to go from here?
Denver Jeans
Hi Denver,
DeleteI hope your back-end is configured correctly? And that you are using an android device?
Cheers,
Jordi
Please refer to these comments:
Deletehttp://delphiworlds.com/2017/04/firebase-cloud-messaging-android-ios/#comment-8666
When the application is closed for notification arrives, however the content is blank.
ReplyDeleteCould help?
This might be of help to you:
Deletehttp://delphiworlds.com/2017/05/add-firebase-cloud-messaging-mobile-apps-part-1/
Thanks for the info David.
DeleteThis is your example that refers to an application is not able to display the content of the notification, only the title is displayed.
ReplyDeleteHi Jordi,
DeleteUsing the firebase code you provided how would I implement the following three endpoints.
The three endpoints with the errors I receive are indicated below:
https://iid.googleapis.com/iid/info/[?details=true|false]
HTTP/1.1 400 Bad Request
https://iid.googleapis.com/iid/v1/IID_TOKEN/rel/topics/TOPIC_NAME
HTTP/1.1 400 Bad Request
https://iid.googleapis.com/iid/v1:batchAdd
{"results":[{"error":"INVALID_ARGUMENT"}]}
I am using Delphi 10.1 upd2 and android ICS 4.0.4 but I am encountering errors in all three methods
The code for the first method (iid/info) I provided in an earlier reply (Alberto Pimentel Antunes comment)
Here's the code for the third method (/batchAdd)
function TFirebaseRest.SubscribeDeviceToTopic(const Token, Topic, APIKey: string): string;
var
IdHTTP: TIdHTTP;
IdIOHandler: TIdSSLIOHandlerSocketOpenSSL;
Response: string;
JsonString: string;
JsonToSend: TStringStream;
begin
IdIOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(Nil);
try
IdIOHandler.ReadTimeout := IdTimeoutInfinite;
IdIOHandler.ConnectTimeout := IdTimeoutInfinite;
IdIOHandler.SSLOptions.Method := sslvSSLv23; //~
IdHTTP := TIdHTTP.Create(Nil);
try
// IdHTTP.ReadTimeout := 30000;
// IdHTTP.HandleRedirects := True;
IdHTTP.IOHandler := IdIOHandler;
IdHTTP.ReadTimeout := IdTimeoutInfinite;
IdHTTP.Request.Connection := 'Keep-Alive';
IdHTTP.Request.CustomHeaders.Add(Format('Authorization: key=%s', [APIKey]));
IdHTTP.Request.ContentType := 'application/json';
IdHTTP.Request.Charset := 'UTF-8'; //+
//IdHTTP.Request.Method := 'POST'; //+
JsonString := '{"to": "/topics/' + Topic + '", "registration_tokens": ["' + Token + '"]}';
JsonToSend := TStringStream.Create(JsonString, TEncoding.UTF8);
try
JsonToSend.Position := 0; //+
Response := IdHTTP.Post('https://iid.googleapis.com/iid/v1:batchAdd', JsonToSend);
Response := Response.Replace(Char(#10), '');
Result := Response;
finally
JsonToSend.Free;
end;
finally
IdHTTP.Free;
end;
finally
IdIOHandler.Free;
end;
end;
I'm using delphi 10.2, and it throws the error:
ReplyDeleteCould not load SSL library
Hi Humberto,
Deleteyou need to include OpenSSL library.
Cheers,
Jordi
Hi Jordi,
ReplyDeleteThank you for the wonderful tutorial and source code.
Looking forward to the follow up article showing how to use the google-services.json and saving tokens.
Many thanks! Definitely!
DeleteI don't get FCM Token....
ReplyDeleteHow to fix my examApp? My Device is Android 7.0
Hi,
DeleteHave you configured your Firebase application?
Cheers,
Jordi
Yes, My project added https://console.firebase.google.com and i got a Sender ID.
DeleteSo you are doing this:
DeletePushService.AppProps[TPushService.TAppPropNames.GCMAppID] := 'SENDER ID';
And you don't get your token?
Cheers,
Jordi
I'm too at this location: No token being received.
DeleteI compile and run FirebaseCloudMessaging application with 10.2 on an Android device and DeviceID show up correctly but "FCM Token" is empty.
- Tried both your sample code unaltered and also with my own SenderID for a project that I think is correctly setup (that's why I also tried your SenderID provided in the source.
No token is being displayed... Only an empty string in both cases :-(
I am too having this problem: No Token is being received.
DeleteI have tried compiling your source FirebaseCloudMessaging using 10.2 both unaltered and also with my own SenderID, but no token is being displayed... device id show up correctly, but no token.
Hi Nicklas,
DeleteWhat version of Android are you using? I might have to test it again and see if this still works.
Cheers,
Jordi
I'm running Android 6.0.1 on a Nexus 5.
DeleteI did however get it to work by simple compiling it all in 10.1!
- No change what so ever to the source code, but compiling in 10.1 make the calls return a Token and I am now successfully pushing messages to both Android and iOS devices :-)
Hope 10.2 get fixed soon...
Yup, probably something has changed with 10.2 version. I'm having quite a lot with issues with it so I might go back to 10.1 as most of my Android projects are not working correctly.
DeleteCheers,
Jordi
Jordi - thanks a lot for this article.
ReplyDeletethanks!
DeleteHello Jordi,
ReplyDeleteThanks for your article.
I have added FMX.PushNotification.android but I get a lot of undeclared identifier error with TPushService, TPushservicenotification, PushService, TPushServiceManager... I'm used a registered Delphi 10.1 Berlin Professional. Any idea of what do I have to add under "uses" or somewhere? Thanks a lot.
Jordi, forget my previous question. I forgot to declare them under Public... Now I don´t get those errors. Thanks.
ReplyDeletesure np. I hope you managed to resolve your issues.
DeleteCheers,
Jordi
I am not receiving the FCM Device Token but am receving the DeviceID. Any idea on what that could be?
ReplyDeleteNot sure why my comments are not getting published.. Apologies if this is a dup.
ReplyDeleteI am not getting an FCM Device Token but I am getting a DeviceID. Any idea why this may be happening?
Maybe the vesion of Delphi? Are you using 10.1?
DeleteHello i'm having the same problem with this ... i Just got the Device ID..
Deletei double checked all critical points
Package Name must be the same in Firebase App and your project
i added and checked the API key / Sender ID, and permissions also in XML
i think that the trick part is on XML manifest
i'm using Delphi 10.2.1
Can you help us with more details about ?
Hi Jr teste,
DeleteIt looks like there is an issue with 10.2 and you might have to go back to 10.1 version. I haven't tried it yet with 10.2 so I might give it a go as I can see quite a lot of people complaining about the same.
Cheers,
Jordi
Hi, Nice Tutorial, i need to ask you
ReplyDelete"response := TFirebaseRest.New.RegisterDeviceToken(DeviceToken, 'xxx');"
what is "xxx" ??
how to keep messages logged in when app closes?
ReplyDeleteIs that possible for Win32 application to receive push notification from Firebase?
ReplyDeleteI guess that something can be done there if the Win32 app knows what to do with that notification.
DeleteCheers,
Jordi
why my APushService: = TPushServiceManager.Instance.GetServiceByName (TPushService.TServiceNames.GCM); come null and void?
ReplyDeleteHello jordi .... sorry i canot do it...
ReplyDeletethere is an error ... http 401 about authontication ... when i second button to register the device.......
Token is empty
ReplyDeleteprobably an issue with Tokyo 10.2 version. Try with 10.1
Deletewhat i should write in this procedure in 'xxxx' ??? i think the problem is here
ReplyDeleteconstructor TFirebaseRest.Create;
begin
{$IFDEF ANDROID}
FOptions := TOptions.Create;
FOptions.FirebaseAuth := 'xxxxxxxxx';
{$ELSE}
FOptions := TOptions.New.Load;
{$ENDIF}
end;
Well, you need to add there your Firebase Auth token there that you should get from your firebase console.
DeleteCheers,
Jordi
thank you for your replay .... there is tooo much key ... server key , API key , web key , legacy key.... sooo boring ... witch one... i try all of them ... and there is alweys http 401 autho error.. thank you sooo much
Deleteyou'll have to keep testing. just make sure you use version 10.1 as I've seen it not working correctly with version 10.2
DeleteCheers,
Jordi
thank you... soooo much .... but im using 10.2... so i'will stop trying... sooo sorry
Deleteis 10.1.2 good or maybe the same problem of 10.2 ????
DeleteHi, im using Tokyo, and im not getting the token. Any solution to this?
ReplyDeletesorry ... in tokyo maybe there is a problem ...
DeleteNot yet. I've just upgraded to the latest version and I will try again and publish my findings.
DeleteCheers,
Jordi
I too, have the problems mentioned by other users, with Tokyo. Will kepp an eye on this thread!
ReplyDeleteCan confirm latest from GitHub doesn't return Device Token when using 10.2.2
ReplyDelete
ReplyDeleteAfter doing several tests, I have no doubt that something is wrong in Tokyo, but when I returned to Berlin everything worked wonders. Hopefully the new versions contemplate this failure. Thanks for the post helped me a lot.
Hi. Thanks for the article. But the source code is unusable. You have used a lot of specific values without any explanation.
ReplyDeleteFor example, what is 'xxxx' in the line:
response := TFirebaseRest.New.RegisterDeviceToken(DeviceToken, 'xxxx');
In the lib.firebase.rest, what is FOptions.FirebaseAuth := '7NZu878Wr56kWm4dSnVIoX52nd02zIRFsoGs7O1y';
Where we can get all these values? There are a lot of keys in Firebase console. Which ones do we need for the code?
Thanks.
Hi Alex,
DeleteIf you follow my article, those questions should be answered. You need to get familiar with Firebase and see where to get those values.
Cheers,
Jordi
Can i know if anyone is able to get fcm token for tokyo?
ReplyDeleteI don't think anyone has been able to make it work so far. I have to try with the latest release and see if that works again.
DeleteCheers,
Jordi
Hello Jordi
ReplyDeleteand sorry for my English , i ask you two question because i have two problems : when i click on the ShowTokenbutton ( i replace button because i dont like use Action list ) i have a error message : " The Java class JgoogleCloudMessaging is unfoundable " and i dont know what i have to do .
My second problems is a second error message on the second button (RegisterDeviceClick )
i have : " Impossible to charge the SSL Library .
OH and you say in your tutorial that you use Google-services.json later but you dont use him can is this the my problem's reason ?
Thanks
Hello jordi,
ReplyDeletesoory for my English, i ask you questions because i have two problems.
Primary when i click on the ShowToken button ( i replace button because i dont know how to use action list) i have a error message :" The java class JGoogleCloudMessaging is unfoundable.
Secondary I have a error message too, but when i click on the registerdevice button :"Impossible to charge the SSL Library".
Oh and in your tutorial you say that you use Google-services.JSON later but you dont use him its possible to be my problem's reason ?
Thanks
You have to use the path RAD Studio 10.2.3 Android Push Notification Patch i had the same issue now solved
DeleteSame here also missing java class
ReplyDeletesame here also no java class
ReplyDeleteExactly the same here.
ReplyDeleteJordi, thanks for the post. But why do you write a this detailled post and then don't help people to find the "FOptions.FirebaseAuth" and TFirebaseRest.New.RegisterDeviceToken(DeviceToken, 'xxxx')???
ReplyDeleteYou only say we need to get familiar with Firebase. I read many documents and tried to find out which keys to use for 8 hours now and couldn't find out. I'm on Delphi Berlin, so it should work if I could set up the correct keys. Please help us
Jordi, you wrote this detailled post, but don't help people to find out which keys to use at TFirebaseRest.New.RegisterDeviceToken(DeviceToken, 'xxxx') and FOptions.FirebaseAuth.
ReplyDeleteWhy do you say we have to get familiar with Firebase instead of helping us? I am looking and trying for 8 hours now to find out which keys to use, but no luck. I am on Delphi Berlin, so it should work if I could set up the correct keys. Please help us!
Hi La Phunk, the code is self explanatory and many others managed to get it running with Delphi Seattle. I don't think it works with Delphi Berlin or Tokyo. I still need to have a look and see what's going on. I will do that soon.
DeleteCheers,
Jordi
Hi Jordi,
ReplyDeleteI can't seem to get a token. I've followed your instructions and haven't gotten past Step 2. The token is blank. I've made the changes to the manifest xml as you specified and setup my app on the firebase console to get a valid server id. I don't know what I'm missing.
I figured it out. I was getting the "java.io.IOException: MAIN_THREAD" exception.
DeleteTo fix it, change the line
ServiceConnection.Active := True;
to
TTask.Run(
procedure
begin
ServiceConnection.Active := True;
end
);
Hello friend. Do you can send me source code.? THe code works with Delphi Tokyio.. Great job. regards from Brazil
ReplyDeleteThis doesn't seem to work in Rio (even with the changes some have indicated above). Anybody get it to work in Rio?
ReplyDeleteRIO 10.3.1 worked android ios
Deletedelphi fmx RIO 10.3.1 push bigImage for URL uses?
ReplyDeleteAnyone accomplished this task on Alexandria 11.1 + FCM + iOS ?
ReplyDelete