I migrated my project from GCM to Firebase. A push notification arrives normally when the device is not sleeping or has recently been sleeping, but if I leave the device for, say, an hour, a push notification is not sent until I activate the device.
Android docs say that if you need to wake your device to deliver a message, use FireBase with high priority. It also says that device administration applications are not subject to Doze restrictions; my application is a device administrator application.
I thought that I would mention that when I transferred the project from GCM to FCM, I specified only the package name in the Firebase console, and not fingerprint.
What i tried
Set priority to high
{ "time_to_live": 300000, "delay_while_idle": false, "android": { "priority": "high" }, "data": { "message": "PING_DEVICE", "time": "21/01/2018 16:20:28", "pushguid": "10062" }, "registration_ids": [ "eOMT........" ] }
The lifetime is set, so the message will come in the end. The delay_ while_idle parameter is false, FCM ignores it after September 2016.
Device administration applications are not subject to Doze, my application is a device administration application, but I also explicitly added the application to the Doze whitelist, which can be found in the section "Settings" → "Battery" → "Optimization". This was done manually through the settings application, NOT programmatically in the code.
I left my device to go to bed for 3 hours, and no jolt passed. I also used ADB to put the device in Doze. When adb puts the device into Doze mode, push is not accepted, and when adb takes the device out of Doze, push passes.
I have not tried further thoughts.
My shocks are data messages. This is because I do not want the click to come to the notification panel on the device and that the user clicks it to execute the function. The user does not interact with the device administrator application. Thus, the data message is processed
onMessageReceived(RemoteMessage remoteMessage)
I believe that notifications cause the device to wake up, which is what I need, but I want the application to handle the push, not the user. Can I have messages that are both notification and data, but onMessageRecievied handle this functionality?
Has anyone experienced something similar or are there any solutions for this?
[EDIT1] Below I find the following link that says you can send a message containing both a notification and data, but if the application is in the background, a notification is displayed, but the data is executed only when the user clicks the notification. This is not what I want, since I would like the data to be executed in onMessageRecived right away.
data notification
[EDIT2] I added the following code and permission for the application. Now the application asks the user to whitelist the application for Doze, so I clicked "yes". I then put the device in Doze through adb and sent a push. Nothing worked until I woke the device from standby. So, unfortunately, this does not work.
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { Intent intent = new Intent(); String packageName = getPackageName(); PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE); if (!pm.isIgnoringBatteryOptimizations(packageName)) { intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS); intent.setData(Uri.parse("package:" + packageName)); startActivity(intent); } } <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
[EDIT3]
I conducted additional testing to try to isolate the problem and deduce the code of my web application from the equation. I put the device in Doze through adb and use the FireBase console to send push. The push code went right. This suggests that there is a problem with the code of my web application that sends all push information to the fcm endpoint. I will receive the code tonight and publish it later.
[EDIT4] I just did some more testing. I put the device into a nap and then used the FireBase console to send a message with two key-value pairs. When the device is in Doze mode and the application is in the foreground (on the screen), a click is performed and OnMessageReceived is executed. It is wonderful. However, if the application is in BG, only a notification is displayed. I understand that from documents, data messages are sent to the launcher via Intent, but my launcher application does not handle clicks. The class that handles clicks is called MyAndroidFirebaseMsgService and extends FirebaseMessagingService.
Should I forward the intention to this class in case the application is in BG? It seems a bit burdensome to do this. This has never happened in GCM.
In addition, I do not want the application to start with a push, because it is very aggressive, because the device user can use another application. My application is also a device administrator’s application, so in 99% of cases there is no user interaction, it’s just a client that runs policies on the device.
[Edit5]
internal static void SendNotification ( Dictionary<string, string> nameValues , List<string> theregIDs , string sPushName) { string stringregIds = string.Join("\",\"", theregIDs) ; JavaScriptSerializer js = new JavaScriptSerializer(); string keyValueJson = js.Serialize(nameValues); string TIME_TO_LIVE = "604800"; string DELAY_WHILE_IDLE = "false"; string ENDPOINTADDRESS = @"https://fcm.googleapis.com/fcm/send"; postData = String.Concat("{\"time_to_live\":", TIME_TO_LIVE, ",\"delay_while_idle\": ", DELAY_WHILE_IDLE, ", \"android\":{\"priority\":\"high\" } ,\"data\": { \"message\" : " + "\"" + sPushName + "\",\"time\": " + "\"" + System.DateTime.Now.ToString() + "\"" , keyValueJson , "},\"registration_ids\":[\"" + stringregIds + "\"]}"); WebRequest myWebRequest = null; WebResponse myWebResponse = null; try { myWebRequest = WebRequest.Create(ENDPOINTADDRESS); myWebRequest.Method = "post"; myWebRequest.ContentType = "application/json";
thanks