I am in the final stage of converting my Android app to B4i (using XUI), and so far the process have been easier, quicker and more joyful than I had ever expected or even hoped for. I will write a post on that process soon.
The last stage in the conversion process is Firebase push messages and notifications, and although it actually works now, the differences between B4i and B4A puzzles me.
Background info: the app is for cat owners who can, amongst many other things, subscribe to cats from certain animal shelters based on criteria such as the shelter's location, the age and gender of the cat etc. Every time a new cat is added in the backend, a single push message with the topic new_cat is sent. When the message is received, the app will check if the last cat added matches the user's criteria and show a notification accordingly.
In B4A the push messages are handled by a service. You grab the push message and create the notification yourself:
In the example above, I use the same topic for all users and in Sub is_this_notification_for_me I check against a REST API if the notification is relevant for that specific user, based on her internal user id. If so, the service will create the notification.
In B4i, the procedure is a bit different. Here there is a notification payload in the JSON, and the topic is prefixed with ios_ as seen in the code from the B4J sending tool:
If the push message arrives while the app is open, the RemoteNotification event will be fired. Here I handle the same code as in B4A:
If the push message arrives while the app is not running, the OS will show the notification automatically with info from the notification payload. When the user clicks on the notification, the app will start and Application_RemoteNotification will be called.
So far, so good. But this is where I am getting a bit confused:
1. Based on my tests, the ios_ prefix doesn't matter. It works fine with the same topic for both Android and IOS. So why is it needed?
2. By accident, I found that if you send the push message with the notification payload to Android, it works just like in IOS: The OS will create the notification for you and the app itself is not even notified. If you click on the notification, the app will start. So apparently, it is possible for B4A to handle Firebase push messages almost like B4i?
3. Although the IOS way is a bit easier with the OS creating the notification for you, there is a problem with it I have not yet solved: How do I decide if the push message is relevant for the given user before launching the app? As shown in the B4A snippet above, the service will check against an API if the message is relevant and only show the notification if so. How do I accomplish the same in B4i where the notification is created automatically?
The last stage in the conversion process is Firebase push messages and notifications, and although it actually works now, the differences between B4i and B4A puzzles me.
Background info: the app is for cat owners who can, amongst many other things, subscribe to cats from certain animal shelters based on criteria such as the shelter's location, the age and gender of the cat etc. Every time a new cat is added in the backend, a single push message with the topic new_cat is sent. When the message is received, the app will check if the last cat added matches the user's criteria and show a notification accordingly.
In B4A the push messages are handled by a service. You grab the push message and create the notification yourself:
B4A:
Sub fm_MessageArrived (Message As RemoteMessage)
Dim topic As String = Message.From
Log($"Message arrived, topic: ${topic}, data: ${Message.GetData}"$)
Wait For(is_this_notification_for_me) Complete (Result As Boolean)
If Result Then
Dim n As Notification
n.Initialize
n.Icon = "icon"
n.SetInfo2(Message.GetData.Get("title"), Message.GetData.Get("body"), "my_tag" & DateTime.Now, Main)
n.Notify(Starter.notificationId)
Else
Log("Not for this user")
End If
End Sub
In the example above, I use the same topic for all users and in Sub is_this_notification_for_me I check against a REST API if the notification is relevant for that specific user, based on her internal user id. If so, the service will create the notification.
In B4i, the procedure is a bit different. Here there is a notification payload in the JSON, and the topic is prefixed with ios_ as seen in the code from the B4J sending tool:
B4J:
If Topic.StartsWith("ios_") Then
Dim iosalert As Map = CreateMap("title": Title, "body": Body, "sound": "default")
m.Put("notification", iosalert)
m.Put("priority", 10)
End If
If the push message arrives while the app is open, the RemoteNotification event will be fired. Here I handle the same code as in B4A:
B4i:
Private Sub Application_RemoteNotification (Message As Map, CompletionHandler As CompletionHandler)
Log($"Message arrived: ${Message}"$)
CompletionHandler.Complete
Wait For(is_this_notification_for_me) Complete (Result As Boolean)
If Result Then
' Do something relevant for this user
Else
Log("Not for this user")
End If
End Sub
If the push message arrives while the app is not running, the OS will show the notification automatically with info from the notification payload. When the user clicks on the notification, the app will start and Application_RemoteNotification will be called.
So far, so good. But this is where I am getting a bit confused:
1. Based on my tests, the ios_ prefix doesn't matter. It works fine with the same topic for both Android and IOS. So why is it needed?
2. By accident, I found that if you send the push message with the notification payload to Android, it works just like in IOS: The OS will create the notification for you and the app itself is not even notified. If you click on the notification, the app will start. So apparently, it is possible for B4A to handle Firebase push messages almost like B4i?
3. Although the IOS way is a bit easier with the OS creating the notification for you, there is a problem with it I have not yet solved: How do I decide if the push message is relevant for the given user before launching the app? As shown in the B4A snippet above, the service will check against an API if the message is relevant and only show the notification if so. How do I accomplish the same in B4i where the notification is created automatically?