Skip to content

PushNotificationBackgroundService still uses deprecated JobIntentService, crashes on Android 16 / low-end devices #6998

Description

@houzx2581396

Description

Description

PushNotificationBackgroundService in amplify_push_notifications still extends the deprecated
androidx.core.app.JobIntentService. On Android 16 (SDK 36) and on low-end Samsung / Oppo / Redmi devices, this triggers a
race in JobParameters.completeWork() that crashes the app with:

java.lang.RuntimeException: An error occurred while executing doInBackground()
Caused by: java.lang.IllegalArgumentException: Given work is not active: JobWorkItem{...
  cmp=<pkg>/com.google.firebase.iid.FirebaseInstanceIdReceiver (has extras) } dcount=1}
  at android.app.job.JobParameters.completeWork(JobParameters.java:503)
  at androidx.core.app.JobIntentService$JobServiceEngineImpl$WrapperWorkItem.complete(JobIntentService.java:273)
  at androidx.core.app.JobIntentService$CommandProcessor.doInBackground(JobIntentService.java:399)

The TODO has been in the code for several minor releases:
https://github.com/aws-amplify/amplify-flutter/blob/main/packages/notifications/push/amplify_push_notifications/android/src/
main/kotlin/com/amazonaws/amplify/amplify_push_notifications/PushNotificationBackgroundService.kt#L24

//TODO(Samaritan1011001): Replace deprecated JobIntentService
class PushNotificationBackgroundService : JobIntentService(), ...

Reproduction

  • amplify_push_notifications: 2.10.2
  • amplify_push_notifications_pinpoint: 2.10.0
  • Flutter: 3.38.10
  • firebase-messaging (transitive): 25.0.1
  • Devices: Samsung A16/A53/A54, Oppo (MediaTek MT6769/MT6873/MT6897), Redmi (Mediatek)
  • OS distribution we see in Play Vitals: Android 16 Beta 52.5%, Android 14 16.9%, Android 13 10.2%
  • Crash frequency increases when the app is held in foreground/idle (e.g. force-update modal) while FCM pushes arrive.

Expected

PushNotificationBackgroundService should use WorkManager (or handle the FCM message synchronously inside
PushNotificationFirebaseMessagingService.onMessageReceived, which already gets ~10s of execution time) instead of the
deprecated JobIntentService.

Additional notes

  • Crashlytics does not capture this (thrown from AsyncTask.done); Play Console Vitals does.
  • JobIntentService was deprecated in androidx.core 1.3.0 and Google recommends WorkManager as replacement.

Categories

  • Analytics
  • API (REST)
  • API (GraphQL)
  • Auth
  • Authenticator
  • DataStore
  • Notifications (Push)
  • Storage

Steps to Reproduce

Steps to Reproduce

  1. Create a Flutter app with amplify_push_notifications: ^2.10.2 and amplify_push_notifications_pinpoint: ^2.10.0
    (transitively pulls in firebase-messaging:25.0.1 and androidx.core:core:1.17.0).

  2. Configure Amplify Pinpoint push notifications normally — no custom Android code needed; the bundled
    PushNotificationFirebaseMessagingService and PushNotificationBackgroundService are auto-registered via the plugin's
    manifest.

  3. Install the app on a low-end Android device running Android 16 Beta (SDK 36), e.g.:

    • Samsung Galaxy A16 / A53 / A54 (Exynos)
    • Oppo with MediaTek MT6769 / MT6873 / MT6897
    • Redmi (MediaTek)
  4. Send several FCM push notifications to the device in quick succession while the app is in the foreground but idle
    easiest way to reproduce is to:

    • Open the app
    • Trigger a blocking modal (e.g. force-update screen) so the user cannot interact
    • Push 3–5 FCM messages within ~30 seconds
    • Wait for the OS to enter Doze / app-standby
  5. Observe in adb logcat (or Play Console → Android Vitals → Crashes after release):

    FATAL EXCEPTION: AsyncTask Initial Commit #1
    java.lang.RuntimeException: An error occurred while executing doInBackground()
    at android.os.AsyncTask$4.done(AsyncTask.java:415)
    ...
    Caused by: java.lang.IllegalArgumentException: Given work is not active:
    JobWorkItem{id=1 intent=Intent { act=com.google.android.c2dm.intent.RECEIVE
    flg=0x11000010 pkg=<your.pkg>
    cmp=<your.pkg>/com.google.firebase.iid.FirebaseInstanceIdReceiver
    (has extras) } dcount=1}
    at android.app.job.JobParameters.completeWork(JobParameters.java:503)
    at androidx.core.app.JobIntentService$JobServiceEngineImpl$WrapperWorkItem.complete(JobIntentService.java:273)
    at androidx.core.app.JobIntentService$CommandProcessor.doInBackground(JobIntentService.java:399)

Why it happens

PushNotificationFirebaseMessagingService.onMessageReceived() calls
PushNotificationBackgroundService.enqueueWork(...), which goes through
androidx.core.app.JobIntentServiceJobScheduler.

On SDK 36 / aggressive OEM ROMs, the system marks the queued JobWorkItem
as inactive (Doze, memory pressure, or stricter background-work enforcement)
before CommandProcessor calls WrapperWorkItem.complete(), causing
JobParameters.completeWork() to throw.

Notes

  • 100% reproducible on Android 16 Beta low-end devices under memory pressure;
    rare but non-zero on Android 13/14.
  • Cannot be caught by Crashlytics because the exception is thrown from
    AsyncTask#done and is not routed through the default uncaught handler
    reliably on all OEM ROMs — only Play Console Vitals captures it.
  • JobIntentService was deprecated in androidx.core:core:1.3.0
    (Sep 2020); recommended replacement is WorkManager or running the work
    synchronously inside FirebaseMessagingService.onMessageReceived
    (which already provides ~10s of guaranteed execution time).

Screenshots

No response

Platforms

  • iOS
  • Android
  • Web
  • macOS
  • Windows
  • Linux

Flutter Version

3.38.10

Amplify Flutter Version

2.10.0

Deployment Method

Amplify Gen 2

Schema

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething is not working; the issue has reproducible steps and has been reproducedpush notifications

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions