Android Question How to send firebase message to a single device

Liew

Member
Licensed User
Dear All,

Can anyone show me the syntax for the Job.GetRequest.SetHeader(xxxxx) in B4J where I can use token ID to send a message instead of API key.

The reason is that I just want to direct the Firebase message to a single device that had subscribe to a topic.

Thanks.

Liew
 

DonManfred

Expert
Licensed User
Hi Erel, I had checked your reply linked to sending message with API key, that will deliver to all devices.
That´s not true.

I am using this and using the fcm token to send to. It REACHES EXTACTLY ONE Device!
 
Last edited:

Liew

Member
Licensed User
That´s not true.

I am using this and using the fcm token to send to. It REACHES EXTACTLY ONE Device!
Hi DonManfred, may I know the syntax parameter is "authorisation", "key="&API or other parameter. The reason is that API is for all devices suscribed to firebase. If I use the token ID obtained from firebase.token, it is not recognized. Kindly enlighten me on this. Thanks
 

Jorge M A

Well-Known Member
Licensed User
The reason is that API is for all devices suscribed to firebase.
This is not exactly this way. The API Key is the registration for you package name.

Read: Integrating Firebase Services[^]
Watch @Erel's Video: FirebaseNotifications - Push messages / Firebase Cloud Messaging (FCM)[^]

You need to identify uniquely each device and subscribe it to same topic as id, for example.

Then, just do that @Erel and @DonManfred already advice you: https://www.b4x.com/android/forum/t...-cloud-messaging-fcm.67716/page-3#post-433583

It doesn't hurt to read the whole thread.
 

DonManfred

Expert
Licensed User
Ok, i´ll try again for you.

This is the code from the Firebasetutorial on how to send to a TOPIC.
B4X:
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}"$)
   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
As the tutorial is registering the Topic general the call of this method should be something like
B4X:
SendMessage("general", "This is the Title", "This is the Body")
It will send a Notification to all devices which is running the samplecode and registering general.

To distinguish i renamed the other sub to make it more clear here

B4X:
Private Sub SendMessage2(id As String, Title As String, Body As String)
   Dim Job As HttpJob
   Job.Initialize("fcm", Me)
   Dim m As Map = CreateMap("to": $"${id}"$)
   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
Here we do not send to a topic. Instead we are facing a specific device resp. Firebase uID.

Each user of your app do have a specifiy Firebase uiD
B4X:
Dim token As String = fm.Token
The token is something like
vEdbT1kp2KRN3LsJPFaIkJLCQXI2
This token can and must be used with SendMessage2.

the call now looks like
B4X:
SendMessage2("vEdbT1kp2KRN3LsJPFaIkJLCQXI2", "This is the Title", "This is the Body")
 

Liew

Member
Licensed User
This is not exactly this way. The API Key is the registration for you package name.

Read: Integrating Firebase Services[^]
Watch @Erel's Video: FirebaseNotifications - Push messages / Firebase Cloud Messaging (FCM)[^]

You need to identify uniquely each device and subscribe it to same topic as id, for example.

Then, just do that @Erel and @DonManfred already advice you: https://www.b4x.com/android/forum/t...-cloud-messaging-fcm.67716/page-3#post-433583

It doesn't hurt to read the whole thread.
Hi Jorge, thanks for pointing out my mistake. As Erel first replied me, the code looks like the FCM tutorial codes and I didn't look at it further. Sorry for causing Erel, DonManfred for the extra work to explain to me further.
So now I know the trick is to make each app subscribe to a unique topic. That means Firebase cannot send message based on token(assigned during first time device subscribe to a topic). Hope that I got it right.
 

Jorge M A

Well-Known Member
Licensed User
Sorry for the late response, due to non-working day here.

It's a bit difficult to propose something more than what @Erel and @DonManfred have already exposed so professionally in the tutorials and threads mentioned, and without knowing more in detail the characteristics of your design.

In my case, for example, I handle three levels of topics: one "general", another related to "e-mail" and another directly to the "license plate" of the driver's specific vehicle, subscribing it in the same way as the "general" topic of the examples.

It is worth mentioning that these data are known by the server application and stored in a database.

B4X:
Public Sub SubscribeToTopics
    fm.SubscribeToTopic("general") 'you can subscribe to more topics
    Log(fm.Token)    '<<<------------ LOOK AT HERE  AND TAKE NOTE OF LONG STRING!
    
    fm.SubscribeToTopic(Starter.eMailID) 'you can subscribe to more topics
    fm.SubscribeToTopic(Starter.plate) 'you can subscribe to more topics
End Sub

That means Firebase cannot send message based on token
Why Not?

However, the token provided by the FirebaseMessaging library works very well, only you must have a mechanism to know it and store it in your server database, to then make the POST of the message to the specific token. Considering that this token can eventually be changed, without me knowing the cause of it. My apologies.

TIP: You need to start the app after install, otherwise messaging service is not created.

I have the slight suspicion that perhaps it is the structure or syntax of the message that could cause confusion, or the way you are sending it.

I hope you can provide more information.
 

Liew

Member
Licensed User
Hi Jorge,

I think you did not get what I meant "That means Google Firebase Cloud messaging cannot send message based on token".

Let me slightly elaborate here:

The B4J example has a method called "Job.GetRequest.SetHeader("Authorization", "key=" & API_KEY)". In this method, the API which was meant for the package ID with Google base is used as authentication. So Firebase will send message to all devices with the package ID with respect to TOPIC subscribed.

My question is instead of using TOPIC, can FireBase send message to ONLY the specific token ID (unique for each device). So can we ask Firebase to send to devices that fulfilled 2 conditions, a) API b) Token ID?

I personally felt using unique TOPIC approach is a bit strange. But however if as you had said the token may change, then of course my propose idea will never work.

As for my application I need not to use the token ID because each of my device will be attached to a panel with unique MAC. So I can just use the MAC as a unique TOPIC. With this my VPS server program can send messages to each device based on their associated MAC.

Thanks.

Regards,

Liew
 
Top