Skip to content
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

TrimMode=full seems to break android push notifications on MAUI .net 9 preview 3 #8940

Closed
jkommeren opened this issue May 11, 2024 · 10 comments · Fixed by #9099
Closed

TrimMode=full seems to break android push notifications on MAUI .net 9 preview 3 #8940

jkommeren opened this issue May 11, 2024 · 10 comments · Fixed by #9099
Assignees
Labels
Area: Linker Issues when linking assemblies. needs-triage Issues that need to be assigned.

Comments

@jkommeren
Copy link

jkommeren commented May 11, 2024

Android application type

.NET Android (net7.0-android, net8.0-android, etc.)

Affected platform version

VS 2022 17.10.0 preview 7

Description

Notifications don't arrive in some cases when "PublishTrimmed" is set to true and building it in Release mode (which is the default)

Point is: @jonathanpeppers suggested to create a new issue here if the issue still persisted on .net 9 preview 3. As far as I'm aware it has been an issue at least since .net 7, but also very likely .net 6.

Originally posted by @jonathanpeppers in #5652 (comment)
Also mentioned in dotnet/maui#16014
And at least some people seem to be affected here dotnet/maui#19900

Steps to Reproduce

  1. Create project in .net 9 preview 3
  2. Add firebase push notification support via Xamarin.Firebase.Messaging" Version="123.3.1.1", google-services.json, etc.
  3. Create a channel with priority max or high, ask for permission to send notifications
  4. Build project in release mode, setting PublishTrimmed to true (and AOT on or off, no difference)
  5. Deploy it to Android device
  6. Launch application
  7. Send notification via Firebase Console with application open, specifying the channel
  8. Notification does not arrive

Did you find any workaround?

Set PublishTrimmed to False or deploying in debug mode fixes the issue immediately: Then the notification does arrive.

Also one odd thing: When the application is in the background, sending a notification via the Firebase console does pop up.
(But if it's sent as a Data message instead, the FirebaseMessagingService does not pick it up in foreground nor background. That is also fixed by using non-trimming or debug)

Maybe there's something I completely don't understand about Android notifications in MAUI, but the way I understand it, Debug should behave like Release mode in these cases right? And Non-trimmed vs Trimmed in Release mode too?

Relevant log output

There is no log output. No unhandled exceptions. Nothing appears to happen when the notification is supposed to arrive.
@jkommeren
Copy link
Author

jkommeren commented May 11, 2024

Also, there is plenty of evidence people seem to be accepting "turning off trimming" as a "solution". But that's not how it should be right?

At the very least it's not clear to the average user (like me) what needs to be done in this case :) please help me solve the issue that has been wrecking my brain for months.

https://stackoverflow.com/questions/76045900/net-maui-why-would-push-notifications-not-work-the-same-after-publishing

#5652

@jonathanpeppers
Copy link
Member

@jkommeren can you share a sample app that shows this issue?

If some code in your app is supposed to be running (and isn't), is the code trimmed away? We could inspect a Release .apk file and see what the difference between PublishTrimmed=true and false is.

Generally, you can preserve a single method as a workaround instead of disabling trimming completely. But you, of course, would need to know which method.

@jkommeren
Copy link
Author

@jkommeren can you share a sample app that shows this issue?

If some code in your app is supposed to be running (and isn't), is the code trimmed away? We could inspect a Release .apk file and see what the difference between PublishTrimmed=true and false is.

Generally, you can preserve a single method as a workaround instead of disabling trimming completely. But you, of course, would need to know which method.

Thank you for your swift reply. How can I inspect the APK? 😊
I think indeed that's where the problem lies.

@jonathanpeppers
Copy link
Member

If you run this tool on an .apk, it can unpack .dll files:

Then you can just open them in ILSpy or your favorite decompiler.

@tranb3r
Copy link

tranb3r commented May 13, 2024

The problem here is that the trimmer is getting rid of an android service in the Plugin.Firebase library, responsible for receiving the notification.
I've already discussed this topic with @jonathanpeppers on discord.
My understanding is that the trimmer cannot "know" that an android service is used by your app. Maybe this could be fixed... who knows.
But the easiest fix (or workaround) is to make sure your app is preserving this service. You can skip trimming for the whole assembly, or add a DynamicDependency attribute in your code path.
A better fix would be to add an Initialize method in the lib, and add the DynamicDependency attribute in this method.
More details here: TobiasBuchholz/Plugin.Firebase#144 (comment)

@tranb3r
Copy link

tranb3r commented May 13, 2024

Also, about inspecting the apk, I've found that the easiest way to do it is to look into YourApp\obj\Release\net8.0-android34.0\android-arm64\linked folder.
In this folder, you'll find all trimmed assemblies after your build, and you can easily open any dll in dnspy.
In Plugin.Firebase.CloudMessaging.dll, look for Plugin.Firebase.CloudMessaging.Platforms.Android.MyFirebaseMessagingService. If it's missing, then the trimmer has been too aggressive, and your notifications won't work.

@jonathanpeppers
Copy link
Member

@jkommeren so are you using TrimMode=full or default settings?

Services should not be trimmed away by default -- it should be using TrimMode=partial by default, which was the same as "SDK only" in the Xamarin days.

@tranb3r
Copy link

tranb3r commented May 13, 2024

Yes this is with full trimming.

@jkommeren
Copy link
Author

jkommeren commented May 13, 2024

@jonathanpeppers yes indeed with full trimming. I think I'm making progress. With the suggestions from tranb3r I have managed to get it working with .net 8 and his library Plugin.Firebase. But then I removed his suggestions, and it was still working (but I'm guessing that's because I didn't do a full clean of obj and bin folders, just from VS)

I'm still a bit puzzled why my own implementation of the FirebaseMessagingService (SuperFirebaseMessagingService.OnMessageReceived) is not being fired though, even though it's present in the DLL (looking at DnSpy), in the linked folder like suggested, and it's working in Debug mode.

I think there's something I'm missing.

I can create a sample project this weekend to upload and have a proper go at .net 9 preview 3. Trimming is definitely different there, it's much slower too :D

Thanks for your help so far.

@jonathanpeppers
Copy link
Member

jonathanpeppers commented May 13, 2024

I wouldn't expect TrimMode=full to work well in .NET 8, as we didn't solve all the trimmer warnings until .NET 9 Preview 3.

But it still seems like there might be some things that we should go test in .NET 9 w/ TrimMode=full:

  • Broadcast receivers
  • Services
  • etc., etc.

I wonder if some of these are trimmed away and shouldn't be.

@jonathanpeppers jonathanpeppers changed the title Trimming still seems to break android push notifications on MAUI .net 9 preview 3 TrimMode=full seems to break android push notifications on MAUI .net 9 preview 3 May 13, 2024
@jpobst jpobst assigned jonathanpeppers and unassigned jpobst May 13, 2024
@jpobst jpobst added the Area: Linker Issues when linking assemblies. label May 13, 2024
jonathanpeppers added a commit to jonathanpeppers/xamarin-android that referenced this issue Jul 11, 2024
…ttribute`

Fixes: dotnet#8940
Context: TobiasBuchholz/Plugin.Firebase#144

Using the NuGet package:

    <PackageReference Include="Plugin.Firebase.CloudMessaging" Version="3.0.0" />

Includes a service:

    namespace Plugin.Firebase.CloudMessaging.Platforms.Android;

    [Service(Exported = true)]
    [IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
    public class MyFirebaseMessagingService : FirebaseMessagingService

Unfortunately, using `TrimMode=full` completely trims away the above
service, which is required for push notifications to work.

I could reproduce this problem in a test using the above NuGet package.

To fix this, we can modify `MarkJavaObjects` to preserve types with
attributes that implement `Java.Interop.IJniNameProviderAttribute`,
and the new test now passes.
@github-actions github-actions bot locked and limited conversation to collaborators Aug 16, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Area: Linker Issues when linking assemblies. needs-triage Issues that need to be assigned.
Projects
None yet
4 participants