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:

Noorul HAQUE

Member
Licensed User
Hi All

I am trying to develop Android App with Firebase Push messaging, I have done following I am using B4A6

1) Created account and App in Firebase
2) downloaded google json file , copied to App folder
3) Edited Manifest file added Google Play Services Base, Firebase Base, Firebase Notification
4) in #Region Project Attributes I added #AdditionalJar: com.google.android.gms : play-services
5) now when I am making Private fm As FirebaseMessaging it showing : unknow type , are you missing a library reference ?

Please advice me if any thing I am missing ...
 

KMatle

Expert
Licensed User
Longtime User

jayel

Active Member
Licensed User
Longtime User
I get this on compiling :
B4A version: 6.00
Parsing code. (0.00s)
Compiling code. Error
Error parsing google-services.json:
Error parsing json file. Make sure that the package name is correct.

Package name is "#ApplicationLabel: testpush"
And project name in firebase is also testpush

Probably a stupid question, but do you have any pointers what the solution is please?
 

DonManfred

Expert
Licensed User
Longtime User
Package name is "#ApplicationLabel: testpush"
That´s NOT the packagename! Press CTRL-B in the IDE to see the packagename.

It must be the same as you defined in firebase console before you download the json file from the console.
 

jayel

Active Member
Licensed User
Longtime User
android side is compiling but the FCMPush on B4J give this on compiling :
Waiting for debugger to connect...
Program started.
java.lang.NoClassDefFoundError: android/app/Service
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
at java.lang.Class.getDeclaredFields0(Native Method)
at java.lang.Class.privateGetDeclaredFields(Class.java:2499)
at java.lang.Class.privateGetPublicFields(Class.java:2530)
at java.lang.Class.getFields(Class.java:1420)
at anywheresoftware.b4a.shell.Shell$FieldCache.getField(Shell.java:813)
at anywheresoftware.b4a.shell.Shell.setStateBeforeUserSub(Shell.java:385)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:288)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:159)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:93)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:90)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:84)
at b4j.example.main.main(main.java:29)
Caused by: java.lang.ClassNotFoundException: android.app.Service
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
... 28 more
java.lang.RuntimeException: java.lang.NoClassDefFoundError: android/app/Service
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:114)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:90)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:84)
at b4j.example.main.main(main.java:29)
Caused by: java.lang.NoClassDefFoundError: android/app/Service
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
Program terminated (StartMessageLoop was not called).
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
at java.lang.Class.getDeclaredFields0(Native Method)
at java.lang.Class.privateGetDeclaredFields(Class.java:2499)
at java.lang.Class.privateGetPublicFields(Class.java:2530)
at java.lang.Class.getFields(Class.java:1420)
at anywheresoftware.b4a.shell.Shell$FieldCache.getField(Shell.java:813)
at anywheresoftware.b4a.shell.Shell.setStateBeforeUserSub(Shell.java:385)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:288)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:159)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:93)
... 3 more
Caused by: java.lang.ClassNotFoundException: android.app.Service
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
... 28 more

 

Noorul HAQUE

Member
Licensed User
Dear Team,

I facing two problems with Firebase Notification,

1st Problem

Firebase notification is only happening if my application is in background working mode, ie, If I am in my App, I am not receiving any notification.

2nd Problem

I have defined newMessage as global variable

Sub Process_Globals
Dim newMessage As Boolean
newMessage = false


and in FireBaseMessaging I have code as below where I have set newMessage as True


Sub fm_MessageArrived (Message As RemoteMessage)
Dim n As Notification
If Message.GetData == Null Or Message.GetData.Get("title") == Null Then
Return
End If
n.Initialize
n.Icon = "icon"
n.SetInfo(Message.GetData.Get("title"), Message.GetData.Get("body") , Main)
Main.newMessage=True
n.Notify(1)
End Sub

Now my problem if I access this variable from Main Module, its value still false even after notification message. My requirement is to set this variable true if any notification arrives, I also tried to save this value in a text file upon receiving notification that also not working.

Please support me on this, thanks in advance.
 
Status
Not open for further replies.
Top