Android Question Push notification - Sending to one device (with the new Firebase API).

davemorris

Active Member
Licensed User
Longtime User
Hi, Guys

Some old posts on the forum suggest that to send a message to a specific device you replace the topic string in the Send() sub with the recipient's device's token.

As I understand the code from Erel's tutorial [B4X] Firebase Push Notifications 2023+ I replace the topic string (originally "general") with the target device's token (i.e. something like "dj7Wz7ukQYe83L-fP4.......")

Sending to a single device:
Private Sub Send (topic As String, title As String, body As String)
    Dim Token As String = GetTokenValue(ServiceAccountFilePath)
    Wait For (SendMessage(topic, title, body)) Complete (Success As Boolean) 'B4A - commend if not needed
    Wait For (SendMessage("ios_" & topic, title, body)) Complete (Success As Boolean) 'B4i - comment if not needed
    ExitApplication
End Sub

Private Sub SendMessage(Topic As String, Title As String, Body As String) As ResumableSub
    Dim Job As HttpJob
    Job.Initialize("", Me)

The simple question is "Is this correct?" or should (with the latest Firebase API) it be done another way.

However, I did try it and it did not work.

Kind regards
Dave
 
Solution
"topic": "dj7Wz7ukQYe83L-fP4WuZl:APA91bE0NQJtZKbauGBoBEENrigNPEAciGodyMHSLPApYdVMZ-Z58kjU88zLnRHKaxiwoiRxv7HaloIWNzLXf3pLswi6U26b14eyTYrWGKXZR9Gc1_naXik"
}
}
ResponseError. Reason: , Response: {
"error": {
"code": 400,
"message": "Request contains an invalid argument.",
"status": "INVALID_ARGUMENT",


you are sending the deviceid AS A TOPIC

Guess ýou need to change the sending code NOT TO USE a topic but instead use token.

See googles documentation.

// Union field target can be only one of the following:
"token": string,
"topic": string,
"condition": string

You can only use ONE of these.
- Use topic if you want to send to a topic. The topic must have been registered.
- use token if you want to send to a...

walterf25

Expert
Licensed User
Longtime User
Hi, Guys

Some old posts on the forum suggest that to send a message to a specific device you replace the topic string in the Send() sub with the recipient's device's token.

As I understand the code from Erel's tutorial [B4X] Firebase Push Notifications 2023+ I replace the topic string (originally "general") with the target device's token (i.e. something like "dj7Wz7ukQYe83L-fP4.......")

Sending to a single device:
Private Sub Send (topic As String, title As String, body As String)
    Dim Token As String = GetTokenValue(ServiceAccountFilePath)
    Wait For (SendMessage(topic, title, body)) Complete (Success As Boolean) 'B4A - commend if not needed
    Wait For (SendMessage("ios_" & topic, title, body)) Complete (Success As Boolean) 'B4i - comment if not needed
    ExitApplication
End Sub

Private Sub SendMessage(Topic As String, Title As String, Body As String) As ResumableSub
    Dim Job As HttpJob
    Job.Initialize("", Me)

The simple question is "Is this correct?" or should (with the latest Firebase API) it be done another way.

However, I did try it and it did not work.

Kind regards
Dave
Check out this thread here

Cheers
 
Upvote 0

davemorris

Active Member
Licensed User
Longtime User
Hi

Thanks for the response but this appears to be a "work around" as each device must subscribe to a topic which is its own Token ID.

I agree it would work but I cannot think this is the correct method to send to individual devices.


Dave
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
Thanks for the response but this appears to be a "work around" as each device must subscribe to a topic which is its own Token ID.
NO! I just do it like this. It is not mandatory.

You can just use the usertoken in the Request to send a Message to this specific ID. NO NEED to use registertopic.

See the Tutorial here https://www.b4x.com/android/forum/threads/b4x-firebase-push-notifications-2023.148715/
and also Googles Documentation here https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages
 
Upvote 0

davemorris

Active Member
Licensed User
Longtime User
Thanks DonManfred

I will give it another try (when I tried it before it did not work).

Kind regards
Dave Morris
 
Upvote 0

davemorris

Active Member
Licensed User
Longtime User
Hi Perhaps I am doing something wrong

You can just use the usertoken in the Request to send a Message to this specific ID. NO NEED to use registertopic.


What I have done
1. Install the Push example code on my phone (it subscribes to "general" topic - and runs it in both debug and and release). The only addition to the code is show the device token on the screen (so I can check it has not changed).
2. Run up the B4j push sender "FCMPush" example code, the only change is the inclusion of the device ID/token and the FCM project files.

Changes to Process_Globals and AppStart() sub:
Sub Process_Globals
    Private Const ProjectId As String = "pushtest2023" ' Taken from firebase project settings.
    Private ServiceAccountFilePath As String = "C:\Projects\B4j_DEV\FCMPush\FireBaseKeyFiles\pushtest2023-firebase-adminsdk-fbsvc-ff4b7ad120.json"
    Private Token As String
End Sub

Sub AppStart (Args() As String)
   
    Dim deviceID As String = "dj7Wz7ukQYe83L-fP4WuZl:APA91bE0NQJtZKbauGBoBEENrigNPEAciGodyMHSLPApYdVMZ-Z58kjU88zLnRHKaxiwoiRxv7HaloIWNzLXf3pLswi6U26b14eyTYrWGKXZR9Gc1_naXik"
   
    Send("general", "this Is the new 012 title", "And this is the new 012 body")

'    Send(deviceID, "Title 001", "Body 001")


    StartMessageLoop
End Sub

3. When Line #11 included and line #13 commented out, it works (the push message is shown on the phone)

And the log shows
----------------------
Waiting for debugger to connect...
Program started.
{
"message": {
"data": {
"title": "this Is the new 012 title",
"body": "And this is the new 012 body"
},
"android": {
"priority": "high"
},
"topic": "general"
}
}
{
"name": "projects/pushtest2023/messages/1204319572461093342"
}
--------

4. However, when #11 is commented out and line #13 is included (push message uses the phone device's ID/token - which I pasted across - so hopefully correct) - It does not work and I get the following error message in the log.
----------
Waiting for debugger to connect...
Program started.
{
"message": {
"data": {
"title": "Title 001",
"body": "Body 001"
},
"android": {
"priority": "high"
},
"topic": "dj7Wz7ukQYe83L-fP4WuZl:APA91bE0NQJtZKbauGBoBEENrigNPEAciGodyMHSLPApYdVMZ-Z58kjU88zLnRHKaxiwoiRxv7HaloIWNzLXf3pLswi6U26b14eyTYrWGKXZR9Gc1_naXik"
}
}
ResponseError. Reason: , Response: {
"error": {
"code": 400,
"message": "Request contains an invalid argument.",
"status": "INVALID_ARGUMENT",
"details": [
{
"@type": "type.googleapis.com/google.firebase.fcm.v1.FcmError",
"errorCode": "INVALID_ARGUMENT"
},
{
"@type": "type.googleapis.com/google.rpc.BadRequest",
"fieldViolations": [
{
"field": "message.token",
"description": "Invalid registration token"
}
]
}
]
}
}
------------------------

It looks to me (from the error response message) that device token for the phone could wrong, but I am sure it is correct as it was pasted it across directly.

Any suggestions?

Kind regards
Dave
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
"topic": "dj7Wz7ukQYe83L-fP4WuZl:APA91bE0NQJtZKbauGBoBEENrigNPEAciGodyMHSLPApYdVMZ-Z58kjU88zLnRHKaxiwoiRxv7HaloIWNzLXf3pLswi6U26b14eyTYrWGKXZR9Gc1_naXik"
}
}
ResponseError. Reason: , Response: {
"error": {
"code": 400,
"message": "Request contains an invalid argument.",
"status": "INVALID_ARGUMENT",


you are sending the deviceid AS A TOPIC

Guess ýou need to change the sending code NOT TO USE a topic but instead use token.

See googles documentation.

// Union field target can be only one of the following:
"token": string,
"topic": string,
"condition": string

You can only use ONE of these.
- Use topic if you want to send to a topic. The topic must have been registered.
- use token if you want to send to a deviceid/token

As written above i do register the devicid as a topic too.
In this case i can use the sendingcode unchanged. for your usecase you need to change the sending-code first to be able to send to a token.
 
Last edited:
Upvote 1
Solution

davemorris

Active Member
Licensed User
Longtime User
Hi. Thanks for the response - it works - I have marked you response as the solution

Guess ýou need to change the sending code NOT TO USE a topic but instead use token.

Just for completeness I have attached the B4J and B4A projects which work using the phone's token - basically they are almost the same as the Push Notification example provided by Erel with DonManfred suggestion applied.

As written above i do register the devicid as a topic too.
In this case i can use the sendingcode unchanged. for your usecase you need to change the sending-code first to be able to send to a token.
I have to say, whilst I can see it would work, I am concerned that in my App there could be 1000s of users and generating too many topics could trigger Google in blocking me in some way.

Thanks for the input.

Now all I have to do is to get it to work on our Web ASP Server which is c# - Not looking forward to that.

Kind regards
Dave
 

Attachments

  • B4A_PushExample_DM.zip
    12.5 KB · Views: 22
  • B4J_FCMPush_DM.zip
    2 KB · Views: 23
Upvote 0
Top