Skip to content

Notifications missing in release build on Android #528

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
gnprice opened this issue Feb 23, 2024 · 4 comments · Fixed by #532
Closed

Notifications missing in release build on Android #528

gnprice opened this issue Feb 23, 2024 · 4 comments · Fixed by #532
Assignees
Labels
a-Android Issues specific to Android, or requiring Android-specific work a-notifications beta feedback Things beta users have specifically asked for

Comments

@gnprice
Copy link
Member

gnprice commented Feb 23, 2024

After the PR #521 which fixed #520, I can no longer reproduce any trouble receiving notifications on Android, regardless of whether the app is already running in the foreground, in the background, or not at all… so long as I'm using a debug build of the app.

But when I run a release build of the app instead — which of course is what we distribute to users — I don't get any notifications at all. Not when the app is in the foreground, not when it's in the background, and not when it's not running.

I'm investigating this now. A quick first observation is that it's unaffected by the @pragma('vm:entry-point') change suggested at #342 (comment) ; it reproduces the same way after I add the pragma.

@gnprice gnprice added a-Android Issues specific to Android, or requiring Android-specific work a-notifications beta feedback Things beta users have specifically asked for labels Feb 23, 2024
@gnprice gnprice added this to the Beta 2 milestone Feb 23, 2024
@gnprice gnprice self-assigned this Feb 23, 2024
@gnprice
Copy link
Member Author

gnprice commented Feb 23, 2024

Hmm! When I reproduce the issue while the app is in the foreground, if I then go to the notification history (system settings > Notifications > Notification history), the notification does appear there! It's under the heading "Recently dismissed".

Still a mystery why the actual visible notification never shows up. But that does mean that our request to show a notification is reaching the relevant Android API. And adding debug logging confirms that the whole chain is getting successfully executed:

  • FCM message (about a notification) reaching the app's broadcast receiver
  • → various package:flutter_firebase logic within Java
  • → corresponding logic in Dart
  • → our notifications code in Dart
  • package:flutter_local_notifications code in Dart
  • → corresponding logic in Java
  • → the point where that code calls the relevant Android API method, androidx.core.app.NotificationManagerCompat.notify.

In light of that, I can also now observe that vm:entry-point pragma making a difference. Without the pragma (i.e. from main), when a notification arrives while in the background, these errors appear on the flutter run --release console:

E/flutter ( 2640): [ERROR:flutter/lib/ui/dart_runtime_hooks.cc(38)] Dart Error: Dart_LookupLibrary: library 'package:zulip/notifications.dart' not found.
E/flutter ( 2640): [ERROR:flutter/shell/common/shell.cc(117)] Dart Error: Dart_LookupLibrary: library 'package:zulip/notifications.dart' not found.
E/flutter ( 2640): [ERROR:flutter/shell/common/shell.cc(117)] Dart Error: Dart_LookupLibrary: library 'package:zulip/notifications.dart' not found.

and the information about the notification never reaches Dart, and no notification appears in the system notification history. When I add that pragma, those errors don't appear, and the behavior when in the background is just like the behavior in the foreground.

So the pragma demonstrably helps, when in the background… but there's some independent issue, later in the pipeline, which is causing the notifications to not actually show up in the normal UI for notifications. That one is still in need of debugging.

gnprice added a commit to gnprice/zulip-flutter that referenced this issue Feb 23, 2024
This fixes part of zulip#528, following the suggestion n-92 made here:
  zulip#342 (comment)

Even with this change, notifications still don't yet work on Android
in release builds.  But after this change, when the app wasn't in
the foreground, they get farther than before.  Specifically they get
just as far as they get, with or without this change, when the app
was in the foreground.  Details here:
  zulip#528 (comment)
@gnprice
Copy link
Member Author

gnprice commented Feb 23, 2024

Aha! Searching the package:flutter_local_notifications issue tracker found the source of the issue. Here's the search I used:
https://github.com/MaikuB/flutter_local_notifications/issues?q=release+debug

There are a number of threads where people report similar symptoms: the notifications work in debug mode, but not in release mode. In several of those threads, the maintainer links to a README section about configuring resource shrinking so that it doesn't discard the notification icon — when the system can't find the specified icon, it rejects the notification.

We don't say anything about resource shrinking or minification or Proguard or anything like that in our own build.gradle. But it turns out Flutter configures it by default in release mode:

            if (shouldShrinkResources(project)) {
                release {
                    // Enables code shrinking, obfuscation, and optimization for only
                    // your project's release build type.
                    minifyEnabled(true)
                    // Enables resource shrinking, which is performed by the Android Gradle plugin.
                    // The resource shrinker can't be used for libraries.
                    shrinkResources(isBuiltAsApp(project))
                    // Fallback to `android/app/proguard-rules.pro`.
                    // This way, custom Proguard rules can be configured as needed.
                    proguardFiles(project.android.getDefaultProguardFile("proguard-android.txt"), flutterProguardRules, "proguard-rules.pro")
                }
            }

That shouldShrinkResources method in turn looks like this:

    private static Boolean shouldShrinkResources(Project project) {
        final String propShrink = "shrink"
        if (project.hasProperty(propShrink)) {
            return project.property(propShrink).toBoolean()
        }
        return true
    }

So we can tell Flutter not to enable shrinking by specifying -Pshrink=false. That looks like this (the -P syntax on the flutter run CLI is helpfully modeled on the same syntax on the gradle CLI):

$ flutter run --release -Pshrink=false

And when I do that, notifications work!

So that confirms the diagnosis: the reason notifications aren't working in release builds is because of this resource shrinking.


It turns out there's also an entry in the Android logs that reports the error. The reason I hadn't seen it before is that it doesn't get reported on the app's own package, but instead on a system package. Here it is (or rather a pair of entries), about 250ms after the call to androidx.core.app.NotificationManagerCompat.notify:

StatusBarIconView       com.android.systemui                 W
No icon for slot com.zulip.flutter/0x131eb018; Icon(typ=RESOURCE pkg=com.zulip.flutter id=0x7f040028)

NotifInflater           com.android.systemui                 W
exception inflating views for 0|com.zulip.flutter|320778264|https://kandra-test.zulipchat.com|101713|dm:101712,101713|10489: com.android.systemui.statusbar.notification.InflationException: Couldn't create icon StatusBarIcon(icon=Icon(typ=RESOURCE pkg=com.zulip.flutter id=0x7f040028) visible user=0 )
  at com.android.systemui.statusbar.notification.icon.IconManager.setIcon(go/retraceme 8fa908dd7f7cdf82919b81f8a849d2e4d6278999a179aaed94e232ba94c0a60d:100)
  at com.android.systemui.statusbar.notification.icon.IconManager.createIcons(go/retraceme 8fa908dd7f7cdf82919b81f8a849d2e4d6278999a179aaed94e232ba94c0a60d:217)
  at com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinderImpl.inflateViews(go/retraceme 8fa908dd7f7cdf82919b81f8a849d2e4d6278999a179aaed94e232ba94c0a60d:123)
  at com.android.systemui.statusbar.notification.collection.NotifInflaterImpl.inflateViewsImpl(go/retraceme 8fa908dd7f7cdf82919b81f8a849d2e4d6278999a179aaed94e232ba94c0a60d:10)
  at com.android.systemui.statusbar.notification.collection.NotifInflaterImpl.inflateViews(go/retraceme 8fa908dd7f7cdf82919b81f8a849d2e4d6278999a179aaed94e232ba94c0a60d:35)
  at com.android.systemui.statusbar.notification.collection.coordinator.PreparationCoordinator.inflateEntry(go/retraceme 8fa908dd7f7cdf82919b81f8a849d2e4d6278999a179aaed94e232ba94c0a60d:38)
  at com.android.systemui.statusbar.notification.collection.coordinator.PreparationCoordinator.inflateRequiredNotifViews(go/retraceme 8fa908dd7f7cdf82919b81f8a849d2e4d6278999a179aaed94e232ba94c0a60d:170)
  at com.android.systemui.statusbar.notification.collection.coordinator.PreparationCoordinator$$ExternalSyntheticLambda1.onBeforeFinalizeFilter(go/retraceme 8fa908dd7f7cdf82919b81f8a849d2e4d6278999a179aaed94e232ba94c0a60d:150)
  at com.android.systemui.statusbar.notification.collection.ShadeListBuilder$$ExternalSyntheticLambda4.accept(go/retraceme 8fa908dd7f7cdf82919b81f8a849d2e4d6278999a179aaed94e232ba94c0a60d:30)
  at com.android.systemui.util.NamedListenerSet.forEachTraced(go/retraceme 8fa908dd7f7cdf82919b81f8a849d2e4d6278999a179aaed94e232ba94c0a60d:46)
  at com.android.systemui.statusbar.notification.collection.ShadeListBuilder$$ExternalSyntheticLambda3.run(go/retraceme 8fa908dd7f7cdf82919b81f8a849d2e4d6278999a179aaed94e232ba94c0a60d:1521)
  at com.android.systemui.statusbar.notification.collection.NotifPipelineChoreographerImpl$frameCallback$1.doFrame(go/retraceme 8fa908dd7f7cdf82919b81f8a849d2e4d6278999a179aaed94e232ba94c0a60d:37)
  at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1341)
  at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1352)
  at android.view.Choreographer.doCallbacks(Choreographer.java:952)
  at android.view.Choreographer.doFrame(Choreographer.java:878)
  at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1326)
  at android.os.Handler.handleCallback(Handler.java:958)
  at android.os.Handler.dispatchMessage(Handler.java:99)
  at android.os.Looper.loopOnce(Looper.java:205)
  at android.os.Looper.loop(Looper.java:294)
  at android.app.ActivityThread.main(ActivityThread.java:8248)
  at java.lang.reflect.Method.invoke(Native Method)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)

So, we have a diagnosis. I think it's now the end of the day for me, but I'll pick this up later to make a fix. (It won't involve -Pshrink — rather we can specifically configure resource shrinking so that it keeps the particular resource we need.)

@gnprice
Copy link
Member Author

gnprice commented Feb 23, 2024

The reason I hadn't seen it before is that it doesn't get reported on the app's own package, but instead on a system package.

(Context here is that the Android logs, aka what logcat shows, are extremely voluminous. So one almost always views them through a filter; the default in Android Studio's logcat UI, which is a sensible one, is to filter it to logs from your own app's package.)

chrisbobbe pushed a commit that referenced this issue Feb 23, 2024
This fixes part of #528, following the suggestion n-92 made here:
  #342 (comment)

Even with this change, notifications still don't yet work on Android
in release builds.  But after this change, when the app wasn't in
the foreground, they get farther than before.  Specifically they get
just as far as they get, with or without this change, when the app
was in the foreground.  Details here:
  #528 (comment)
@chrisbobbe
Copy link
Collaborator

Interesting—thanks for doing all this investigation! Looking forward to a fix, and I've just merged #529.

gnprice added a commit to gnprice/zulip-flutter that referenced this issue Feb 23, 2024
…away

Details in the new comment and in the issue thread.

Fixes: zulip#528
chrisbobbe pushed a commit that referenced this issue Feb 24, 2024
…away

Details in the new comment and in the issue thread.

Fixes: #528
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
a-Android Issues specific to Android, or requiring Android-specific work a-notifications beta feedback Things beta users have specifically asked for
Projects
Status: Done
Development

Successfully merging a pull request may close this issue.

2 participants