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: 900
Last edited:

rad

Member
Licensed User
Longtime User
Hi all...

I have implement this library with successful, although sending notification from firebase console sometimes getting null value...
But when I try sending notification from B4A :

B4X:
#Region  Project Attributes
    #ApplicationLabel: Simpush
    #VersionCode: 1
    #VersionName: Simple
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: portrait
    #CanInstallToExternalStorage: False
#End Region

#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: True
#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.
    Private const API_KEY As String = "AIzaSyAQ7XJnHBD1lz2z2rJpGvmKtF4O4Hy9J0Q"
End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.

    Private btnPush As Button
End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    Activity.LoadLayout("frmMain")
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Private Sub SendMessage(Topic As String, Title As String, Body As String)
   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


Sub JobDone(job As HttpJob)
   Log(job)
   If job.Success Then
     Log(job.GetString)
   End If
   job.Release
End Sub

Sub btnPush_Click
    SendMessage("general", "Test", "This is only notification test")
End Sub

It's nothing happen... no notification arise..
Can anyone help me to solve this issue?

I can not use B4J sample because:
1. I don't have B4J (I only have B4A, and I always develop my application using B4A)
2. My Current/Existing application which will be add FCM Service are developed from B4A.
 

Alpandino

Member
Licensed User
Hi all...

I have implement this library with successful, although sending notification from firebase console sometimes getting null value...
But when I try sending notification from B4A :

B4X:
#Region  Project Attributes
    #ApplicationLabel: Simpush
    #VersionCode: 1
    #VersionName: Simple
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: portrait
    #CanInstallToExternalStorage: False
#End Region

#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: True
#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.
    Private const API_KEY As String = "AIzaSyAQ7XJnHBD1lz2z2rJpGvmKtF4O4Hy9J0Q"
End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.

    Private btnPush As Button
End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    Activity.LoadLayout("frmMain")
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Private Sub SendMessage(Topic As String, Title As String, Body As String)
   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


Sub JobDone(job As HttpJob)
   Log(job)
   If job.Success Then
     Log(job.GetString)
   End If
   job.Release
End Sub

Sub btnPush_Click
    SendMessage("general", "Test", "This is only notification test")
End Sub

It's nothing happen... no notification arise..
Can anyone help me to solve this issue?

I can not use B4J sample because:
1. I don't have B4J (I only have B4A, and I always develop my application using B4A)
2. My Current/Existing application which will be add FCM Service are developed from B4A.

Hi rad,
when you send a message from an app you're not sending a notification, but a message that you'll receive inside a specific service called FirebaseMessaging (the name must be this) and in a specific sub called "fm_MessageArrived". In this case it's up to you decide what to do whit this message (do an action, show a notification, modify a db table, etc).
In your code you're sending a message to the topic called "general", so this message will be received by any device using your app registered to this topic.
When you send a message from the firebase console, instead, you're sending a notification that will appear on the notification bar only if your app is in background.

Bye
 

rad

Member
Licensed User
Longtime User
Hi rad,
when you send a message from an app you're not sending a notification, but a message that you'll receive inside a specific service called FirebaseMessaging (the name must be this) and in a specific sub called "fm_MessageArrived". In this case it's up to you decide what to do whit this message (do an action, show a notification, modify a db table, etc).
In your code you're sending a message to the topic called "general", so this message will be received by any device using your app registered to this topic.
When you send a message from the firebase console, instead, you're sending a notification that will appear on the notification bar only if your app is in background.

Bye

Hi Alpandino,
Thanks for the enlightenment...
 

rad

Member
Licensed User
Longtime User
Don't use Firebase Console. You are just wasting your time.

Start with testing your implementation with the B4J code. B4J is free: https://www.b4x.com/b4j.html

You can later move the code to B4A. It is very very simple.

OK Erel, I will try to install B4J first, and I will report the progress soon...
Thanks...
 

rad

Member
Licensed User
Longtime User
b4j.jpg


Hi Erel...

please explain me, what is wrong with the image above conditions...
coz I have no idea about java programming... :(
 
Last edited:

Smee

Well-Known Member
Licensed User
Longtime User
I will soon be renewing my B4A licence but in the meantime I have been the topics on FBM with a view to implementaion into an app I am writing. The java snippet looks exactly like B4A. Why would that code not work within B4A
 

trueboss323

Active Member
Licensed User
Longtime User
Is there any chance there would be added support for sending messages from the Firebase console?
 
Status
Not open for further replies.
Top