Android Question A little confused about Push Notifications

FrostCodes

Active Member
Licensed User
Hello everyone, I have over 25k users I want to send push notifications to using FCM. I have implemented the example made by Erel and have been using it for some time now but I was very curious about something so I add my analytics tracking code to the event of when a new notification arrives. I noticed that even though in the past 30 days I have more than 6k active users, only about 490 received my push notifications. I thought this is weird as the example in the forum said that it would work both in foreground and background mode which I tested it but today I decided to sit down and test it with multiple phones, I tested it with android 7, 8 and I noticed that I only receive it when

1) The app is open currently
2) Or when I minimized or pressed the back button and the app is still in my recently open android app list.

I don't know if this is normal or not but my aim with push notifications was even if you just turned on your phone or haven't opened my app in a long time I can use it to make you remember about my app so I did something; I made a service that uses StartServiceAt() and auto-starts every 1 hour with the Firebase code :


B4X:
CallSubDelayed(FirebaseMessaging, "SubscribeToTopics")

and then I retested my app in release mode again and I quit it and even cleared the recently used app list and I pushed a notification with @Erel Fcm sending tool and the notification works perfectly well even without my app been opened at all.

So I am confused is something wrong with my first code or its normal and for what I want, it's better I use the second code to achieve it.
Thanks!

EDIT:

The first code I meant is EREL example .. here
and the second code is just the example but I added a new service that uses StartServiceAt to call the sub below every 1 hour
B4X:
CallSubDelayed(FirebaseMessaging, "SubscribeToTopics")
 
Last edited:

FrostCodes

Active Member
Licensed User
I don't want to be negative :)
yes, something changed. testing using the b4j demo, the phone is not always receiving the pushs any more like last year for example, but it works nice when sending push notifications from firebase console.
In fact, last time playing with the push notifications for my Takeaways-App the phone received the push from B4J-demo the next day (some push notifications online),
then I was thinking ohh! maybe I just sent too many push notifications from b4j-demo, maybe :p


Yes I did test this also and it works if you send as a notification... I don't know if it does works for a longer period but it works the only thing is it spoils my app icon and changes it to a circle then the feature I built into the firebase events don't work... Maybe I would look at it again and see if I can extract the keys from the notification objects... Thanks
 
Upvote 0

FrostCodes

Active Member
Licensed User
Best option is to send data messages only with high priority (throw an own notification then). In the app option (long click the icon) set energy saving to "none". Works for me. Search the forum or the Google docs for the options.
Hi Kmatle... This is already what I did... I even attached screenshots of my app energy saving mode... The issue is it's not my phone almost all my users said they don't receive it... So definately it's not something that simple the way I see it

Thanks
 
Upvote 0

FrostCodes

Active Member
Licensed User
Yeah, I saw that. But what I wrote was about how the other apps do it. I mean, if there's a time-based pattern like that in Tik Tok one could interpret it to mean "we couldn't get it to work unless we use a timer to wake up", which would be interesting also.
Facebook does have a pattern like that I am very sure of this... The tik tok own I am not so sure but usually I get the push notification in the morning and evening especially... So I think it's possible also
 
Upvote 0

KMatle

Expert
Licensed User
Hm. Just tried an old example. The app was installed months ago on my phone with Android 11 (didn't test it since then). Just sent a message and it did arrive on time (with a delay of some seconds). This is the code I use:

B4X:
Dim Job As HttpJob
   Job.Initialize("SendMessage", Me)
  
   Dim m As Map = CreateMap("to": $"${Devtoken}"$)
   Dim data As Map = CreateMap("data": MyData)
    Dim pri As Map=CreateMap("priority":"high") ' <- important
    m.Put("data", data)
    m.Put("android", pri)
 
   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)

Maybe the message arrives BUT the notification isn't thrown. You can log (for a test) if and when the message arrives.
 
Upvote 0

FrostCodes

Active Member
Licensed User
Hm. Just tried an old example. The app was installed months ago on my phone with Android 11 (didn't test it since then). Just sent a message and it did arrive on time (with a delay of some seconds). This is the code I use:

B4X:
Dim Job As HttpJob
   Job.Initialize("SendMessage", Me)
 
   Dim m As Map = CreateMap("to": $"${Devtoken}"$)
   Dim data As Map = CreateMap("data": MyData)
    Dim pri As Map=CreateMap("priority":"high") ' <- important
    m.Put("data", data)
    m.Put("android", pri)

   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)

Maybe the message arrives BUT the notification isn't thrown. You can log (for a test) if and when the message arrives.
Hi, I already tried this.. I would share the PHP code I also tried to use to test also with something similar. The only difference in our code is you targeted just one device while I am targeting a whole topic but it's the same thing it works for some time after you recently opened the app and after that, it doesn't. I wanted to confirm did you open your app before you tested or reinstalled it from b4a bridge then tested it, because if you did that yes it would work but give it some time like let's say 30 minutes to 2 hours.. it won't work again.
 
Upvote 0

FrostCodes

Active Member
Licensed User
My PHP code is this @KMatle

PHP:
<?php
error_reporting(E_ALL);

function notify ($title, $message)
{
    // API access key from Google API's Console
    define( 'API_ACCESS_KEY', 'GET YOURS FROM YOUR FIRBASE CONSOLE');
   
    // prep the bundle
    $msg = array
    (
        'title'     => $title,
        'body'     => $message  
    );
    $fields = array
    (
        'to' => '/topics/general',
        'android' => array('priority' =>'high'),
        'priority' => 'high',
        'data' => $msg
    );
   
    $headers = array
    (
        'Authorization: key=' . API_ACCESS_KEY,
        'Content-Type: application/json'
    );
   
    $ch = curl_init();
    curl_setopt( $ch,CURLOPT_URL, 'https://fcm.googleapis.com/fcm/send' );
    curl_setopt( $ch,CURLOPT_POST, true );
    curl_setopt( $ch,CURLOPT_HTTPHEADER, $headers );
    curl_setopt( $ch,CURLOPT_RETURNTRANSFER, true );
    curl_setopt( $ch,CURLOPT_SSL_VERIFYPEER, false );
    curl_setopt( $ch,CURLOPT_POSTFIELDS, json_encode( $fields ) );
    $result = curl_exec($ch );
    curl_close( $ch );
    return $result;
}

var_dump(notify('🥳 Civic Education exam? Don\'t fail it!', '✅ Practice now with Examina!'));
 
Last edited:
Upvote 0

KMatle

Expert
Licensed User
Can you log (to a file perhaps) when a message arrives? Maybe arriving works but not anything else? I did some tests some time ago which showed that the data messages do arrive but the device slept and throwing a notification (by own code) did not work until I switched on the device.

In the B4A app I use this code including settting the partial wakelock from the phone library (don't know if this really, really helps). The notification is thrown with high priority, too.

"MyData" is a map I send in the fcm message.

B4X:
    pws.PartialLock
    Dim n As NB6
    MyIcon = LoadBitmapResize(File.DirAssets, "someicon.jpg", 24dip, 24dip, False)
    n.Initialize("default", Application.LabelName, "HIGH").AutoCancel(True).SmallIcon(MyIcon)
    n.Build("FCM", "Message sent: " & MyData.get("time") & ", Notification created at " & DateTime.Time(DateTime.Now), "tag1", Main).Notify(4)
    pws.ReleasePartialLock

Additionally from the Google docs:

Setting the priority of a message

You have two options for assigning delivery priority to downstream messages on Android: normal and high priority. Delivery of normal and high priority messages works like this:

  • Normal priority. This is the default priority for data messages. Normal priority messages are delivered immediately when the app is in the foreground. When the device is in Doze, delivery may be delayed to conserve battery. For less time-sensitive messages, such as notifications of new email, keeping your UI in sync, or syncing app data in the background, choose normal delivery priority.
    When receiving a normal priority message on Android that requests a background data sync for your app, you can schedule a task with WorkManager to handle it when the network is available.
  • High priority. FCM attempts to deliver high priority messages immediately, allowing the FCM service to wake a sleeping device when necessary and to run some limited processing (including very limited network access). High priority messages generally should result in user interaction with your app or its notifications. If FCM detects a pattern in which they don't, your messages may be de-prioritized. Android P introduced app standby buckets which limit the number of FCM high priority messages you can send to your app that don't result in the user using your app or viewing a notification. If, in response to a high priority message, a notification is displayed in a way that is visible to the user, then your app standby bucket quota will not be consumed by that message.
 
Upvote 0

FrostCodes

Active Member
Licensed User
the device slept and throwing a notification (by own code) did not work until I switched on the device.
I actually did the tests with the devices on and off and the same issue. I just tested with the partial lock now and it doesn't fix the problem.
I am running a test to see what is happening to the firebase service in the background I hope I can fix it with this. :(
 
Upvote 0

Sandman

Well-Known Member
Licensed User
Maybe the message arrives BUT the notification isn't thrown
I have noticed something related to this.

In my daily phone I use Messages from Google as my SMS app. Using that app means I also can have https://messages.google.com/ open in a browser window on my desktop computer. The phone and that window are connected so I can both read and write my SMS messages from the comfort of my computer. When a message arrive and the desktop windows sees it, it throws up a notification on my monitor. Pretty much like how the Android phone shows a notification when a SMS message arrives.

So far so good. The strange thing I've noticed many times is that the computer shows the message BEFORE the phone. Let's go through the steps to be sure what happens:

1. Somebody sends me a SMS message
2. Phone receive it
3. Phone send it to Google to show on the webpage
4. Webpage receive message and show notification
5. Time passes (0-10 minutes)
6. Phone display notification

So perhaps Android is simply very unwilling to light up the screen to show a notification (that in many cases are not even seen by the user). You know, as a battery-saving thing. It would mean that the message actually arrive as it should, it's just that the phone doesn't inform the user.

If this is correct, then I suppose we should use code to wake the phone briefly when we get a message so it reasons "oh, screen is lit, I might as well show this waiting notification"

Note that I have no actual evidence of anything here, other than the fact that the phone often shows the notifications after the computer. The rest is just my best guess.
 
Upvote 1

FrostCodes

Active Member
Licensed User
I have noticed something related to this.

In my daily phone I use Messages from Google as my SMS app. Using that app means I also can have https://messages.google.com/ open in a browser window on my desktop computer. The phone and that window are connected so I can both read and write my SMS messages from the comfort of my computer. When a message arrive and the desktop windows sees it, it throws up a notification on my monitor. Pretty much like how the Android phone shows a notification when a SMS message arrives.

So far so good. The strange thing I've noticed many times is that the computer shows the message BEFORE the phone. Let's go through the steps to be sure what happens:

1. Somebody sends me a SMS message
2. Phone receive it
3. Phone send it to Google to show on the webpage
4. Webpage receive message and show notification
5. Time passes (0-10 minutes)
6. Phone display notification

So perhaps Android is simply very unwilling to light up the screen to show a notification (that in many cases are not even seen by the user). You know, as a battery-saving thing. It would mean that the message actually arrive as it should, it's just that the phone doesn't inform the user.

If this is correct, then I suppose we should use code to wake the phone briefly when we get a message so it reasons "oh, screen is lit, I might as well show this waiting notification"

Note that I have no actual evidence of anything here, other than the fact that the phone often shows the notifications after the computer. The rest is just my best guess.
Thanks this gave me a good idea which I would try out. Maybe this can help fix the issue.
 
Upvote 0

FrostCodes

Active Member
Licensed User
Hi after a lot of tests and me reading every single post related to push notification in the forum, I noticed something the services seem to be running fine in the android emulator but not the multiple phones I tested with.

I read on the android official blog that it's supposed to work fine but there are a lot of manufacturers that are forcing our apps to be fully killed and when this happens, all services including firebase would be killed for our app but for major apps like WhatsApp, they are whitelisted and won't be affected unfortunately again I found out that almost nobody knows how to get into the whitelist list.

This is very sad as android is supposed to be a free OS, not one in which only the big player gets more benefits. I am tired of testing and testing so I guess for now I would be giving up on push notifications and would be looking at email marketing and bulk SMS marketing for my app. Yes, this costs me money and is not as effective as push notifications but what can I do? The phone manufacturers have decided to be killing our apps since we are the smaller players in the market, it's annoying but oh well... I would keep looking for better ways to reach out to my users.

Thanks to everyone who tried to help figure out this issue.
 
Upvote 0

FrostCodes

Active Member
Licensed User
This is one of the articles I read, I would edit this post if I find the rest

 
Upvote 0

Erel

Administrator
Staff member
Licensed User
Many developers use push notifications and they mostly work. In some cases the messages don't arrive immediately, and in a fewer cases messages are lost. This is how this system works.

The fact that your messages don't arrive after restarting the device means that you did something wrong. I recommend you to start from scratch and carefully follow the tutorial. Don't use PHP. Don't use Firebase Console.

This is one of the articles I read, I would edit this post if I find the rest
It is difficult for me to help you as you post things that have nothing to do with push notifications.
 
Upvote 0

Erel

Administrator
Staff member
Licensed User
I will repeat as I'm not sure that you believe me:

Push notifications have nothing to do with running services.
Push notifications have nothing to do with running services.
Push notifications have nothing to do with running services.
Push notifications have nothing to do with running services.
Push notifications have nothing to do with running services.
Push notifications have nothing to do with running services.
Push notifications have nothing to do with running services.
Push notifications have nothing to do with running services.
Push notifications have nothing to do with running services.
Push notifications have nothing to do with running services.

When the OS receives a data message it starts your FirebaseMessagingService service. There are other options but this is how the current implementation work.
 
Upvote 0

Sandman

Well-Known Member
Licensed User
there are a lot of manufacturers that are forcing our apps to be fully killed and when this happens, all services including firebase would be killed for our app
Yep, no surprise there. Before throwing in the towel and starting to send your users postcards, I have to ask if you considered trying this:

1. Add a service with StartServiceAt that runs (for instance) every two hours
2. Check if Firebase service us running, and start it if needed
3. Wait for a while (ten seconds?) to let Firebase do its thing
4. If there's a push message received, do a phone.KeepAlive(true) to light the screen
5. Give the phone OS a chance to display the notification (for ten seconds?)
6. Do a ReleaseKeepAlive


Note: I do realize that what I wrote above shouldn't be needed in a perfect world. I'm just trying to find a pragmatic solution.

Note 2: There's been several new messages posted in this thread since I started writing this. I might be completely wrong in my suggestion, but I'll post it in case it does help somehow.
 
Upvote 0
Top