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

Status
Not open for further replies.
Updated tutorial: https://www.b4x.com/android/forum/threads/b4x-firebase-push-notifications-2023.148715/


Clarification: The nice thing about FCM is that your app doesn't need to run in order to receive messages. The FirebaseMessaging receiver 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 Receiver named FirebaseMessaging to your app (must be this name):
B4X:
Sub Process_Globals
    Private fm As FirebaseMessaging
End Sub

Private Sub Receiver_Receive (FirstTime As Boolean, StartingIntent As Intent)
    If FirstTime Then
        fm.Initialize("fm")
    End If
    fm.HandleIntent(StartingIntent)
End Sub

Public Sub SubscribeToTopics
    fm.SubscribeToTopic("general")
End Sub

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

Sub fm_TokenRefresh (Token As String)
    Log("TokenRefresh: " & Token)
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: 1,124
Last edited:

Philip Prins

Active Member
Licensed User
Longtime User
Hello Erel

On the Firebase console it mentions that support for Server key s will be ended and that you should use Firebase Cloud Messaging tokens instead.
How to use these tokens?
 

Philip Prins

Active Member
Licensed User
Longtime User
Hello

If i swipe my app away i will not receive any notifications from firebase messaging, if i do this with whatsapp for example i will still receive messages for whatsapp.
Should the Firebase messaging service start my Starter service again when receiving a message?

It looks like my App and starter service are not activated when receiving an FCM message
 
Last edited:

Philip Prins

Active Member
Licensed User
Longtime User
Yes it very strange, it seems the service doesn't respond to FCM when in the background.
I don't get an error from Firebase analytics.
When i have the phone connected to USB the App works well ,no errors in the log and FCM messages will arrive.
When i leave the phone for a number of hours and sent a fcm message the app will not respond, i also tried the high priority option mentioned on the forum.
It looks like the service is killed and will not respond to FCM messages.
On another phone a Motorola G the app keeps working but on a Huawei Honor 6 the app stops , i disabled the battery optimise function but that did not resolve it.
 

Philip Prins

Active Member
Licensed User
Longtime User
Can you post the call to Google's webservice? (= send request)

B4X:
Public Sub SendMessage(Topic As String, Title As String )
   Dim Body As String="Test"
   Dim Job As HttpJob
   Job.Initialize("fcm", Me)
  Dim m As Map = CreateMap("to": $"/topics/${Topic}"$, "priority": "high")
   Dim data As Map = CreateMap("title": Title, "body": Body)
   m.Put("data", data)
   Dim jg As JSONGenerator
   jg.Initialize(m)
   Job.PostString("https://fcm.googleapis.com/fcm/send", jg.ToString)
   Job.GetRequest.SetContentType("application/json;charset=UTF-8")
   Job.GetRequest.SetHeader("Authorization", "key="& " api key")
End Sub
 

KMatle

Expert
Licensed User
Longtime User
Dim m As Map = CreateMap("to": $"/topics/${Topic}"$, "priority": "high")

Looks good. I have a Huwaei, too (P8) which works even after days without any action. Maybe there's another thing you've disabled?

I only send messages to single devices with

B4X:
Dim m As Map = CreateMap("to": $"${Devtoken}"$)

Could you copy the devtoken to a string and try again (just to see if there is a problem with sending to a topic)

Just another try:

B4X:
 Dim m As Map = CreateMap("to": $"${Devtoken}"$)
   Dim noti As Map = CreateMap("body":"Notification ","title":"Just a title")
   Dim data As Map = CreateMap("data": datastring)
   m.Put("notification", noti)
   m.Put("data", data)
   Dim jg As JSONGenerator
   jg.Initialize(m)
   Job.Tag=jg
   Job.PostString("https://fcm.googleapis.com/fcm/send", jg.ToString)
   Job.GetRequest.SetContentType("application/json;charset=UTF-8")
   Job.GetRequest.SetHeader("Authorization", "key=" & API_KEY)

This is a notification & data message which causes android to generate a notification (automatically) when the app is in the background.
 

Philip Prins

Active Member
Licensed User
Longtime User
I have tried it and sending a topic is working both with your example as with my code.
The app receives the message when in the background but after a while it looks like the app is killed and the FCM message does not wake it up.
I get no errors from google analytics
 

KMatle

Expert
Licensed User
Longtime User
I don't think that it is related. The program doesn't need to run for the messages to arrive.
The program will start automatically.

Unfortunately it doesn't. I have tested this. On my Huawei P8 (6.0) even the Google Calendar widget did not update and I had to change the settings (took me some time to find the reason). The (German) header ist saying "To save energy, background tasks will be "turned off" when the screen is switched off. Apps like mail, sms, social media, etc. will NOT be updated...."

It seems that are some "known" apps like WhatsApp which will get the "run in background" setting automatically (a month ago I got an extra Huawei Update for this) When I install a new (own) app on my phone I have to switch it on. I have spent some hours to check that because my app "did not receive messages while in the background".

Changing the manifest doesn't help here:

... according to this stack overflow question, developers can't include in their manifest asking for inclusion in protected apps list but Huawei OS apparently includes for popular apps, like Tinder/Instagram...

http://stackoverflow.com/questions/...setting-on-huawei-phones-and-how-to-handle-it
 
Status
Not open for further replies.
Top