B4A Library FirebaseNotifications - Push messages / Firebase Cloud Messaging (FCM)

Status
Not open for further replies.

Clarification: The nice thing about FCM is that your app doesn't need to run in order to receive messages. The FirebaseMessaging service will be started by the OS when a new message arrives.
It is not a real issue, but if the user closed your app with a "force close" from the device settings then messages will not arrive, until the app is started again.
On some misbehaving devices, killing the app with a swipe will also cause messages not to arrive, until the app is started again.

Firebase Cloud Messaging service is a layer above Google Cloud Messaging service.
It makes it simple to add support for push messages.

Sending messages is done with a simple HTTP request. It is also possible to send message from the Firebase console, though it is not very useful and is actually more complicated than using the REST api.

1. The first step is to follow the Firebase integration tutorial:
https://www.b4x.com/android/forum/threads/integrating-firebase-services.67692/

Make sure to add the Notifications snippet.
You should also reference FirebaseAnalytics

2. Add a Service named FirebaseMessaging to your app (must be this name):
B4X:
Sub Process_Globals
   Private fm As FirebaseMessaging
End Sub

Sub Service_Create
   fm.Initialize("fm")
End Sub

Public Sub SubscribeToTopics
   fm.SubscribeToTopic("general") 'you can subscribe to more topics
End Sub

Sub Service_Start (StartingIntent As Intent)
   If StartingIntent.IsInitialized Then fm.HandleIntent(StartingIntent)
   Sleep(0)
   Service.StopAutomaticForeground 'remove if not using B4A v8+.
End Sub

Sub fm_MessageArrived (Message As RemoteMessage)
   Log("Message arrived")
   Log($"Message data: ${Message.GetData}"$)
   Dim n As Notification
   n.Initialize
   n.Icon = "icon"
   n.SetInfo(Message.GetData.Get("title"), Message.GetData.Get("body"), Main)
   n.Notify(1)
End Sub

Sub Service_Destroy

End Sub

fm_MessageArrived will be raised whenever a message is received. In this case we show a notification. You can do whatever you need.

We call SubscribeToTopics from the starter service to make sure that the app will be subscribed when it starts:
B4X:
'Starter service
Sub Process_Globals

End Sub

Sub Service_Create
   CallSubDelayed(FirebaseMessaging, "SubscribeToTopics")
End Sub

Now we can send messages to a "topic" and all the subscribed devices will receive it.

See the code in the attached B4J tool. Note that the API_KEY should be set in the B4J code. It shouldn't be distributed in your app.

API_KEY is the server key from:

SS-2017-04-07_08.10.47.png


A simple non-ui B4J program is attached.

Note that messages sent from Firebase Console will not arrive in some cases. Use the B4J code to test it.
 

Attachments

  • B4J-SendingTool.zip
    1.1 KB · Views: 2,133
Last edited:

Manolete

Member
Licensed User
Hello, is there a chance to add an "Action" to the Notificarion?
Like when you receive a Twitter notification, there is a row in the bottom of the notification with a couple of actions like "Share" or somotehing like that.

Is this possible?

Thanks,
Manolete
 

Manolete

Member
Licensed User
Hi DonManfred,

Thanks a lot, I will use it right now!

I appreciate the excellent help and support.
Regards,
Manuel
 

Croïd

Active Member
Licensed User
Please where thread solution #272 ?

works fine with console firebase only !

B4X:
[jobname=fcm, success=true, username=
, password=, errormessage=, target=class b4j.example.main
, taskid=1, req=anywheresoftware.b4h.okhttp.OkHttpClientWrapper$OkHttpRequest@3c4b1fb8, tag=java.lang.Object@7267e742
, fx=anywheresoftware.b4j.objects.JFX@2fac8a71, httputils2service=null]
{"message_id":8878541930547848266}
 
Last edited:

Croïd

Active Member
Licensed User
I saw the PICTURE!
And i told you to post errors as text. In a newly created thread.

DON´T expect any more answers from me. I´ll put you on my ignore list. I´n not interested in helping here. Even i´m not interestent to spent my time for this.

Good luck.

Sorry Don, I modified to not mislead others !! and I deleted image as requested
 

Croïd

Active Member
Licensed User
A last try to help:
Based on the error the server key seems to be wrong.
Look at the FCM tutorial and watch out how to get the server-key
Use the serverkey to send a notification.

Thanks Don and Sincerely sorry for my mistake
 

Kwame Twum

Active Member
Licensed User
Hello everyone, I'd like to know if the FCM Sender ID is mentioned any where in the Library or it's implementation. An app I'm building currently can't receive messages from my server nor from the FCM notifications console. I've been through all the necessary steps.

I cURLed the FCM server with both the Server Key and a generated Token from the app and got back the response in red:

B4X:
curl --header "Authorization: key=AAAAeArR1Dg:APA91bH4GAkOSEcnLU-XXXXXXWB29u70MUM7wQ" \
     --header Content-Type:"application/json" \
     https://fcm.googleapis.com/fcm/send \
     -d "{\"registration_ids\":[\"cHKKRHRVVWw:APA91XXXXXXXXOaB1kl2t8\"]}"

{"multicast_id":8444809106756048113,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"MismatchSenderId"}]}

I've reported the matter to the FCM support and apparently, the Server key doesn't match the Sender ID. I know the Server Key is correct because I copied it from the FCM Console. The Sender ID however is not mentioned anywhere in my app. So the MismatchSenderId error is quite baffling.

The google-services.json file however contains the correct Sender ID from the FCM console.
FCM support asked me to check my code as I might be generating a token for multiple sender id. A bit confused here. Any help is greatly appreciated. Thank you.

PS. I already have another app working well with FCM, it sends and receives payloads just fine. So I know I've done what needs to be done.


EDIT: SOLVED!
I found this file: googleservices.xml in the res/values folder.

I guess this file is supposed to be deleted and regenerated on every compile. But it somehow stays the same. My guess is: It's been so ever since a previously deleted FCM project I used and this xml file mentions the Sender ID from the deleted project.

The file was marked readonly, after removing the readonly attribute and recompiling, it now references the correct Sender ID. I hope this helps someone else.
 
Last edited:

peacemaker

Expert
Licensed User
What is the use of
B4X:
If StartingIntent.IsInitialized AND fm.HandleIntent(StartingIntent) Then Return
?
Why Return ?
 

paul fredrick

Member
Licensed User
i have tested FirebaseNotification and FirebaseAuth... works, but i would like to store the token when user subscribe with google-service or with another metod

Public Sub SubscribeToTopics
fm.SubscribeToTopic("general") 'you can subscribe to more topics
Log(fm.token)
End Sub

when user sign in store ID in authentication tab, but this ID not works to SendMessageToSingleDevice

Sub Auth_SignedIn (User As FirebaseUser)
Log("SignedIn: " & User.DisplayName)
lblName.Text = "Hello: " & User.DisplayName
auth.GetUserTokenId(User,False)
End Sub

Thanks
 

incendio

Well-Known Member
Licensed User
Is there a time limitation for unsent notification to the devices?

For example, targeted devices not have internet connection for a week, will notification still send after devices get active internet connection?
 
Status
Not open for further replies.
Top