Android Tutorial Setting up Firebase messaging in 5 minutes

Important for Huawei users (or others):

Make sure your energy settings don't pause your app (even the firebase service). Huawei calls it "protected apps". If your app isn't protected, the app will be completely paused when the screen is turned off! Yes, even the service! On my P8 I wondered why my Google Calendar widget did not update. That's the reason why.

Huwei OS has a list with "known apps" like fb and WhatsApp. Here it is set to protected automatically.

whatsapp-notifications-not-working-or-getting-delayed.jpg






This is a quick guide how to

- set up a fresh app
- creating a new firebase project in the Firebase console

to receive Firebase messages.

First follow Erel's tutorial: https://www.b4x.com/android/forum/t...-messages-firebase-cloud-messaging-fcm.67716/

Important here:

- add "Android Support Repository" and "Google Repository" via SDK-manager
- copy the firebase lib (jar & xml) to the additional lib's folder
- create a new app with Erel's code :)
- add FirebaseNotifications from the libs tab
- edit the manifest and add these lines

B4X:
'************ Google Play Services Base ************
AddApplicationText(
   <activity android:name="com.google.android.gms.common.api.GoogleApiActivity"
  android:theme="@android:style/Theme.Translucent.NoTitleBar"
  android:exported="false"/>
    <meta-data
  android:name="com.google.android.gms.version"
  android:value="@integer/google_play_services_version" />
)
'************ Google Play Services Base (end) ************
'************ Firebase Base ************
CreateResourceFromFile("google-services", "google-services.json")
AddPermission(android.permission.ACCESS_NETWORK_STATE)
AddPermission(android.permission.INTERNET)
AddPermission(android.permission.WAKE_LOCK)
AddPermission(com.google.android.c2dm.permission.RECEIVE)
AddPermission(${applicationId}.permission.C2D_MESSAGE)
AddManifestText( <permission android:name="${applicationId}.permission.C2D_MESSAGE"
  android:protectionLevel="signature" />)
AddApplicationText(
<receiver
  android:name="com.google.android.gms.measurement.AppMeasurementReceiver"
  android:enabled="true">
  <intent-filter>
  <action android:name="com.google.android.gms.measurement.UPLOAD"/>
  </intent-filter>
  </receiver>

  <service
  android:name="com.google.android.gms.measurement.AppMeasurementService"
  android:enabled="true"
  android:exported="false"/>
   <provider
  android:authorities="${applicationId}.firebaseinitprovider"
  android:name="com.google.firebase.provider.FirebaseInitProvider"
  android:exported="false"
  android:initOrder="100" />
    <receiver
  android:name="com.google.android.gms.measurement.AppMeasurementReceiver"
  android:enabled="true">
  <intent-filter>
  <action android:name="com.google.android.gms.measurement.UPLOAD"/>
  </intent-filter>
  </receiver>

  <service
  android:name="com.google.android.gms.measurement.AppMeasurementService"
  android:enabled="true"
  android:exported="false"/>
   <receiver
  android:name="com.google.firebase.iid.FirebaseInstanceIdReceiver"
  android:exported="true"
  android:permission="com.google.android.c2dm.permission.SEND" >
  <intent-filter>
  <action android:name="com.google.android.c2dm.intent.RECEIVE" />
  <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
  <category android:name="${applicationId}" />
  </intent-filter>
  </receiver>
    <receiver
  android:name="com.google.firebase.iid.FirebaseInstanceIdInternalReceiver"
  android:exported="false" />


  <service
  android:name="com.google.firebase.iid.FirebaseInstanceIdService"
  android:exported="true">
  <intent-filter android:priority="-500">
  <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
  </intent-filter>
  </service>
)
'************ Firebase Base (end) ************
'************ Firebase Notifications ************
AddApplicationText(
    <service
  android:name="com.google.firebase.messaging.FirebaseMessagingService"
  android:exported="true">
  <intent-filter android:priority="-500">
  <action android:name="com.google.firebase.MESSAGING_EVENT" />
  </intent-filter>
  </service>
   <service android:name="anywheresoftware.b4a.objects.FirebaseNotificationsService">
     <intent-filter>
  <action android:name="com.google.firebase.MESSAGING_EVENT"/>
     </intent-filter>
   </service>
)
'************ Firebase Notifications (end)************

Open your browser and go to https://console.firebase.google.com/

1.JPG


Click on "Create new project" and give it a name


Select "Add Firebase to your Android app"

2.JPG


Set your app's package name (B4A -> Build configurations)

3.JPG


In the console use THE SAME name:

4.JPG


No need to enter more at this moment! Just click on "Add app"

Save the google-services.json to the main folder of your app


5.JPG


Under the tab "Cloud Messaging" you see the Firebase Messaging token and the Server key. Both are good for the API-Key in the B4J-App in Erel's example:

B4X:
Job.GetRequest.SetHeader("Authorization", "key=" & API_KEY) ' this goes here...

It is recommended to use the token (the "server key" is deprecated). Right now both work.

6.JPG


Compile your app (debug) and set a brakepoint here

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

Copy the token (this is the device's token) to the clipboard.

For a quick test: In the Firebase console select your project and click on "notifications":

8.JPG


Paste the token and enter a message text

Run your app and press "Send message".

Your app will receive the message in a second (don't forget a breakpoint here):

B4X:
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
 

Attachments

  • 7.JPG
    7.JPG
    15.6 KB · Views: 767
Last edited:

kelvo01

Member
Licensed User
Longtime User
i download FCMPush from erel tutorial but don't work.

"
Waiting for debugger to connect...
Program started.
<HTML>
<HEAD>
<TITLE>Unauthorized</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000">
<H1>Unauthorized</H1>
<H2>Error 401</H2>
</BODY>
</HTML>
[jobname=fcm, success=false, username=
, password=, errormessage=Unauthorized, target=class b4j.example.main
, taskid=1, req=anywheresoftware.b4h.okhttp.OkHttpClientWrapper$OkHttpRequest@9807454, tag=java.lang.Object@3d494fbf
, httputils2service=null]
"
 

KMatle

Expert
Licensed User
Longtime User
Unauthorized = wrong API-Key or from another app

Use this to send the message (You need the device token - see the logs of the app to get it from FCM.Token) OR the topic's name. The API_Key must be set (global variable here)

B4X:
Private Sub SendMessageToSingleDevice(Devtoken As String, datastring As String)

   Dim Job As HttpJob
   Job.Initialize("SendMessage", Me)

   Dim m As Map = CreateMap("to": $"${Devtoken}"$)
   Dim noti As Map = CreateMap("body":"Notification ", "title":"New message!")
   Dim data As Map = CreateMap("data": datastring)
   m.Put("notification", noti)
   m.Put("data", data)
   m.Put("content_available": True)
   Dim jg As JSONGenerator
   jg.Initialize(m)
   Job.Tag=jg
   Log(jg.ToString)
   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

for a topic:

B4X:
Private Sub SendMessageToTopic(Topic As String, datastring As String)

   Dim Job As HttpJob
   Job.Initialize("SendMessage", Me)
 
    Dim m As Map = CreateMap("to": $"/topics/${Topic}"$)
   Dim noti As Map = CreateMap("body":"Notification ", "title":"New message!")
   Dim data As Map = CreateMap("data": datastring)
   m.Put("notification", noti)
   m.Put("data", data)
   m.Put("content_available": True)
   Dim jg As JSONGenerator
   jg.Initialize(m)
   Job.Tag=jg
   Log(jg.ToString)
   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
 

kelvo01

Member
Licensed User
Longtime User
Where i take the exact API KEY

I found ; web key API AI......................................
isn't ?

Andrea
 

ldb68

Member
Licensed User
Longtime User
Hi
Sending merssage from andorid app it's ok. I receive data.

Sending message from console the data I receive is empty:
Log: Message arrived
Log: Message data: {}

The text message from console need some special format??

thanks
 

Cableguy

Expert
Licensed User
Longtime User
Important for Huawei users (or others):

Make sure your energy settings don't pause your app (even the firebase service). Huawei calls it "protected apps". If your app isn't protected, the app will be completely paused when the screen is turned off! Yes, even the service! On my P8 I wondered why my Google Calendar widget did not update. That's the reason why.

Huwei OS has a list with "known apps" like fb and WhatsApp. Here it is set to protected automatically.

View attachment 50770





This is a quick guide how to

- set up a fresh app
- creating a new firebase project in the Firebase console

to receive Firebase messages.

First follow Erel's tutorial: https://www.b4x.com/android/forum/t...-messages-firebase-cloud-messaging-fcm.67716/

Important here:

- add "Android Support Repository" and "Google Repository" via SDK-manager
- copy the firebase lib (jar & xml) to the additional lib's folder
- create a new app with Erel's code :)
- add FirebaseNotifications from the libs tab
- edit the manifest and add these lines

B4X:
'************ Google Play Services Base ************
AddApplicationText(
   <activity android:name="com.google.android.gms.common.api.GoogleApiActivity"
  android:theme="@android:style/Theme.Translucent.NoTitleBar"
  android:exported="false"/>
    <meta-data
  android:name="com.google.android.gms.version"
  android:value="@integer/google_play_services_version" />
)
'************ Google Play Services Base (end) ************
'************ Firebase Base ************
CreateResourceFromFile("google-services", "google-services.json")
AddPermission(android.permission.ACCESS_NETWORK_STATE)
AddPermission(android.permission.INTERNET)
AddPermission(android.permission.WAKE_LOCK)
AddPermission(com.google.android.c2dm.permission.RECEIVE)
AddPermission(${applicationId}.permission.C2D_MESSAGE)
AddManifestText( <permission android:name="${applicationId}.permission.C2D_MESSAGE"
  android:protectionLevel="signature" />)
AddApplicationText(
<receiver
  android:name="com.google.android.gms.measurement.AppMeasurementReceiver"
  android:enabled="true">
  <intent-filter>
  <action android:name="com.google.android.gms.measurement.UPLOAD"/>
  </intent-filter>
  </receiver>

  <service
  android:name="com.google.android.gms.measurement.AppMeasurementService"
  android:enabled="true"
  android:exported="false"/>
   <provider
  android:authorities="${applicationId}.firebaseinitprovider"
  android:name="com.google.firebase.provider.FirebaseInitProvider"
  android:exported="false"
  android:initOrder="100" />
    <receiver
  android:name="com.google.android.gms.measurement.AppMeasurementReceiver"
  android:enabled="true">
  <intent-filter>
  <action android:name="com.google.android.gms.measurement.UPLOAD"/>
  </intent-filter>
  </receiver>

  <service
  android:name="com.google.android.gms.measurement.AppMeasurementService"
  android:enabled="true"
  android:exported="false"/>
   <receiver
  android:name="com.google.firebase.iid.FirebaseInstanceIdReceiver"
  android:exported="true"
  android:permission="com.google.android.c2dm.permission.SEND" >
  <intent-filter>
  <action android:name="com.google.android.c2dm.intent.RECEIVE" />
  <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
  <category android:name="${applicationId}" />
  </intent-filter>
  </receiver>
    <receiver
  android:name="com.google.firebase.iid.FirebaseInstanceIdInternalReceiver"
  android:exported="false" />


  <service
  android:name="com.google.firebase.iid.FirebaseInstanceIdService"
  android:exported="true">
  <intent-filter android:priority="-500">
  <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
  </intent-filter>
  </service>
)
'************ Firebase Base (end) ************
'************ Firebase Notifications ************
AddApplicationText(
    <service
  android:name="com.google.firebase.messaging.FirebaseMessagingService"
  android:exported="true">
  <intent-filter android:priority="-500">
  <action android:name="com.google.firebase.MESSAGING_EVENT" />
  </intent-filter>
  </service>
   <service android:name="anywheresoftware.b4a.objects.FirebaseNotificationsService">
     <intent-filter>
  <action android:name="com.google.firebase.MESSAGING_EVENT"/>
     </intent-filter>
   </service>
)
'************ Firebase Notifications (end)************

Open your browser and go to https://console.firebase.google.com/

View attachment 50439

Click on "Create new project" and give it a name


Select "Add Firebase to your Android app"

View attachment 50440

Set your app's package name (B4A -> Build configurations)

View attachment 50441

In the console use THE SAME name:

View attachment 50442

No need to enter more at this moment! Just click on "Add app"

Save the google-services.json to the main folder of your app


View attachment 50443

Under the tab "Cloud Messaging" you see the Firebase Messaging token and the Server key. Both are good for the API-Key in the B4J-App in Erel's example:

B4X:
Job.GetRequest.SetHeader("Authorization", "key=" & API_KEY) ' this goes here...

It is recommended to use the token (the "server key" is deprecated). Right now both work.

View attachment 50444

Compile your app (debug) and set a brakepoint here

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

Copy the token (this is the device's token) to the clipboard.

For a quick test: In the Firebase console select your project and click on "notifications":

View attachment 50446

Paste the token and enter a message text

Run your app and press "Send message".

Your app will receive the message in a second (don't forget a breakpoint here):

B4X:
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
All that in 5 minutes???
Just downloading the repo would take ages for me!
 

rad

Member
Licensed User
Longtime User
Hi
Sending merssage from andorid app it's ok. I receive data.

Sending message from console the data I receive is empty:
Log: Message arrived
Log: Message data: {}

The text message from console need some special format??

thanks

Hi ldb68...

I not success yet to sending message from android app...
But if I send a message from console, the data I received sometime null...
 

VictorTandil

Member
Licensed User
Longtime User
Is it possible for the APIKEY to change from time to time? How do I get the new APIKEY from the code?

It happened that with the app working properly, suddenly one day I stopped sending and receiving messages and in the "Job" it says that I am not authorized
 

JEG

Member
Licensed User
Longtime User
I have created the same app with different package names on two devices. The logs of both apps show that they are sending and receiving their own messages to/from the server, however, they don't receive anything from the other device.

If I send a message from A using B token fro the log I get on A screen the "Message sent/ the message/ time from etc. No message is received on B
 

JEG

Member
Licensed User
Longtime User
Firebase messaging in 5 minutes - Problem

Proceeded as follows
1 Copied FMC_Show pasted as FBBase
2 Changed Package to SA.ED.FBBase
3 In firebase
a. Create FBBase/South Africa
b. Add firebase to android app Package = SA.ED.FBBase
c. Register app
d. Download GoogleServices Json
e. Got services key token
4 In App FBBase
a. Paste token as FCM_Key
b. Changed MY Name to FarmBase
5 Compiled to ASUS tablet via bridge
a. Pass Error “There was a problem parsing the package”
b. Inactivated following lines in Manifest

AddManifestText( <permission android:name="${applicationId}.permission.C2D_MESSAGE" android:p rotectionLevel="signature" />)​
6 Re-Compiled to ASUS tablet
a. Log


Logger connected to: asus ME371MG
--------- beginning of /dev/log/main
Copying updated assets files (1)
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
no extras

*** Service (firebasemessaging) Create ***
FarmBase_192.168.1.7
** Service (firebasemessaging) Start **
{"content_available":true,"data":{"data":{"FCMToken":"","NickName":"FarmBase_192.168.1.7","MessType":"ImHere"}},"to":"\/topics\/all"}
*** Service (httputils2service) Create ***
** Service (httputils2service) Start **
Back from Job:SendMessageTopic
Response from server: {"message_id":7077560981545958573}
OK

** Service (firebasemessaging) Start **
Message arrived
Message data: {data={"FCMToken":"","MessType":"ImHere","NickName":"FarmBase_192.168.1.7"}}
ID: 0:1499244335459091%bcb1963cf9fd7ecd
From: /topics/all
Collapse:
(MyMap) {data={"FCMToken":"","MessType":"ImHere","NickName":"FarmBase_192.168.1.7"}}
adding chats...

7 Repeated as above with Name Changed to FBCell1 and package to SA.ED.FBCell1. Complied to Huawei Cell phone
8 Nothing received from other device
 
Last edited:

JEG

Member
Licensed User
Longtime User
Firebase messaging in 5 minutes - Problem

Proceeded as follows
1 Copied FMC_Show pasted as FBBase
2 Changed Package to SA.ED.FBBase
3 In firebase
a. Create FBBase/South Africa
b. Add firebase to android app Package = SA.ED.FBBase
c. Register app
d. Download GoogleServices Json
e. Got services key token
4 In App FBBase
a. Paste token as FCM_Key
b. Changed MY Name to FarmBase
5 Compiled to ASUS tablet via bridge
a. Pass Error “There was a problem parsing the package”
b. Inactivated following lines in Manifest

AddManifestText( <permission android:name="${applicationId}.permission.C2D_MESSAGE" android:p rotectionLevel="signature" />)
6 Re-Compiled to ASUS tablet
a. Log


Logger connected to: asus ME371MG
--------- beginning of /dev/log/main
Copying updated assets files (1)
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
no extras

*** Service (firebasemessaging) Create ***
FarmBase_192.168.1.7
** Service (firebasemessaging) Start **
{"content_available":true,"data":{"data":{"FCMToken":"","NickName":"FarmBase_192.168.1.7","MessType":"ImHere"}},"to":"\/topics\/all"}
*** Service (httputils2service) Create ***
** Service (httputils2service) Start **
Back from Job:SendMessageTopic
Response from server: {"message_id":7077560981545958573}
OK

** Service (firebasemessaging) Start **
Message arrived
Message data: {data={"FCMToken":"","MessType":"ImHere","NickName":"FarmBase_192.168.1.7"}}
ID: 0:1499244335459091%bcb1963cf9fd7ecd
From: /topics/all
Collapse:
(MyMap) {data={"FCMToken":"","MessType":"ImHere","NickName":"FarmBase_192.168.1.7"}}
adding chats...

7 Repeated as above with Name Changed to FBCell1 and package to SA.ED.FBCell1. Complied to Huawei Cell phone
8 Nothing received from other device
 
Top