TobiasBuchholz / Plugin.Firebase

Wrapper around the native Android and iOS Firebase Xamarin SDKs
MIT License
211 stars 49 forks source link

.NET MAUI and AOT compilation #258

Closed kalpasrl closed 3 months ago

kalpasrl commented 7 months ago

In our project if I use the release configuration in Android, the compilation is done in AOT and in this case push notifications are not received. Is there a problem with trimming assemblies?

Plugin.Firebase.CloudMessaging version 2.0.4

Thank you

tranb3r commented 7 months ago

@kalpasrl If you're using the trimmer, make sure it does not get rid of Plugin.Firebase.CloudMessaging.Platforms.Android.MyFirebaseMessagingService. Also, please copy/paste your csproj here, there may be something wrong in it.

kalpasrl commented 7 months ago

My csproj is:

<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|net7.0-android|AnyCPU'">
    <AndroidPackageFormats>apk;aab</AndroidPackageFormats>
    <DefineConstants>$(DefineConstants);RELEASE;</DefineConstants>
    <RunAOTCompilation>True</RunAOTCompilation>
    <Optimize>True</Optimize>
    <PublishTrimmed>True</PublishTrimmed>
</PropertyGroup>

What is the way to exclude FirebaseMessagingService from trimming?

tranb3r commented 7 months ago

Ok, so it's indeed trimming (PublishTrimmed), not AOT (RunAOTCompilation), which is causing trouble.

I've described the same issue here: https://github.com/TobiasBuchholz/Plugin.Firebase/issues/144#issuecomment-1716038986

The easiest workaround is to skip trimming for the Plugin.Firebase.CloudMessaging assembly: <TrimmerRootAssembly Include="Plugin.Firebase.CloudMessaging" RootMode="All" />

kalpasrl commented 7 months ago

Thank you @tranb3r

RunAOTCompilation cannot be used without PublishTrimmed=true

Quaybe commented 7 months ago

Ok, so it's indeed trimming (PublishTrimmed), not AOT (RunAOTCompilation), which is causing trouble.

I've described the same issue here: #144 (comment)

The easiest workaround is to skip trimming for the Plugin.Firebase.CloudMessaging assembly: <TrimmerRootAssembly Include="Plugin.Firebase.CloudMessaging" RootMode="All" />

This workaround no longer works for me. I'm not sure why. I believe I had trimming enabled with the TrimmerRootAssembly excluding Plugin.Firebase in my csproj file and it had working in the past, but not now.

I've tried RootMode="Library" as well with no luck. I am forced to disable trimming completely until this issue is fixed with Firebase.

tranb3r commented 7 months ago

it had working in the past, but not now

What did you change? My recommandation would be to inspect the dll after build, in order to check the result of the trimmer. This would allow you to know whether your csproj is properly configured or not.

Quaybe commented 7 months ago

it had working in the past, but not now

What did you change? My recommandation would be to inspect the dll after build, in order to check the result of the trimmer. This would allow you to know whether your csproj is properly configured or not.

I updated Visual Studio.

I tried all sorts of recommended variations to get the trimming to leave Plugin.Firebase or Plugin.Firebase.Messaging alone, but it no longer works.

My issue is, when trimming is enabled, I do get a notification from Firebase, but it's as if my app is in the background even though I have it in the foreground. I have logic built in to ignore the notifications from OnMessageReceieved if my app is in the foreground and certain pages are focused. With trimming enabled, OnMessageReceived is ignored completely and I get the notification as if my app isn't open at all. Trimming off, works fine, but only if I turn it off completely.

kalpasrl commented 6 months ago

@jfversluis Unfortunately, even with the latest fixes made on .NET Android, the problem persists.

frank-ami-ict commented 6 months ago

I’ve gotten it to work in release by using these settings in the csproj:

`False

false`
Quaybe commented 6 months ago

I’ve gotten it to work in release by using these settings in the csproj:

<RunAOTCompilation>False</RunAOTCompilation> <PublishTrimmed>false</PublishTrimmed>

Isn't that just turning off AOT Compilation and Trimming for everything?

frank-ami-ict commented 6 months ago

I’ve gotten it to work in release by using these settings in the csproj: <RunAOTCompilation>False</RunAOTCompilation> <PublishTrimmed>false</PublishTrimmed>

Isn't that just turning off AOT Compilation and Trimming for everything?

Correct, but it was the only way for me to get it to run properly. If a better way presents itself I'll gladly hop aboard. Spent enough time trying to fix strange Maui quirks.

Quaybe commented 6 months ago

Yeah, I'm in the exact same boat. Just wanted to make sure I understood correctly.

angelru commented 5 months ago

Push notifications work for me https://github.com/angelru/ValdemoroEn1/blob/dev/src/ValdemoroEn1/ValdemoroEn1.csproj#L91 https://github.com/angelru/ValdemoroEn1/blob/dev/src/ValdemoroEn1/ValdemoroEn1.csproj#L107 https://github.com/angelru/ValdemoroEn1/blob/dev/src/ValdemoroEn1/Platforms/Android/proguard.cfg

kalpasrl commented 4 months ago

@angelru I tried your suggestions but it doesn't work for me

jkommeren commented 4 months ago

I'm also having the issue, I think. To be clear I think there's a clear distinction of what is and what isn't working. Could everyone confirm we're having the same issue?

With trimming on the following breaks for me ("publishtrimmed" set to true, along with aot, but also with aot off)

The only thing that works:

They all work fine when trimming is disabled along with aot.

I've even tried "linker issues free" .net 9 preview 3, but that still has the issue . (And some other issues of course)

@angelru @kalpasrl could you please confirm which of these cases are working for you?

I've also taken the liberty to file an issue here https://github.com/xamarin/xamarin-android/issues/8940

kalpasrl commented 4 months ago

@jkommeren I confirm that notification with data type message don't work. I receiving regular notification because are managed by operating sysstem and not by the app.

tranb3r commented 4 months ago

@jkommeren @kalpasrl I have all scenarios working in my app. So there must be something wrong in your app. I insist you should check that you still have Plugin.Firebase.CloudMessaging.Platforms.Android.MyFirebaseMessagingService in your assembly after trimming. The notification won't work if the trimmer gets rid of this android service (which is happening by default).

jkommeren commented 4 months ago

@jkommeren @kalpasrl I have all scenarios working in my app. So there must be something wrong in your app. I insist you should check that you still have Plugin.Firebase.CloudMessaging.Platforms.Android.MyFirebaseMessagingService in your assembly after trimming. The notification won't work if the trimmer gets rid of this android service (which is happening by default).

So thats by using the DynamicDependency attribute right? I'll try it right away when I get home!

tranb3r commented 4 months ago

I think there are two ways to preserve this service (both are working):

jkommeren commented 4 months ago

Thanks man, it looks like I'm getting there!

The TrimmedRootAssembly suggestion entry did not seem to do anything (maybe because trim was set to full by default? I just put it into an item group in csproj like this (I had done it previously for another dependency that failed because it was trimmed) `

`

... But adding the DynamicDependency [DynamicDependency(DynamicallyAccessedMemberTypes.All, "Plugin.Firebase.CloudMessaging.Platforms.Android.MyFirebaseMessagingService", "Plugin.Firebase.CloudMessaging")] Like you suggested to the top of my AppShell constructor did work with your library! :) Data messages are being received. I can't believe it. Thanks so much!

tranb3r commented 4 months ago

The TrimmedRootAssembly suggestion entry did not seem to do anything (maybe because trim was set to full by default? I just put it into an item group in csproj like this (I had done it previously for another dependency that failed because it was trimmed) <ItemGroup> <TrimmerRootAssembly Include="Plugin.Firebase.CloudMessaging" RootMode="All" /> </ItemGroup>

It should definitely work with full trimming mode. And actually, it's not needed if you do not trim in full mode. Most probably you did not clean properly before rebuild. If you want to try again, make sure you close VS and remove bin & obj folders, before rebuilding your app.

... But adding the DynamicDependency [DynamicDependency(DynamicallyAccessedMemberTypes.All, "Plugin.Firebase.CloudMessaging.Platforms.Android.MyFirebaseMessagingService", "Plugin.Firebase.CloudMessaging")] Like you suggested to the top of my AppShell constructor did work with your library! :) Data messages are being received. I can't believe it. Thanks so much!

You're welcome. Just be careful with this fix. It's actually more a workaround. It could break if the code of Plugin.Firebase changes. The idea is to make sure the service is preserved. But this should actually be part of the plugin initialization.

kalpasrl commented 4 months ago

@jkommeren I'm happy for you, unfortunately it still doesn't work for me. Upon receiving a notification, logcat writes this:

05-15 17:27:45.340 21162 23707 I NotificationManager: com.company.app: notify(1337, null, Notification(channel=null shortcut=null contentView=null vibrate=null sound=null defaults=0x0 flags=0x10 color=0x00000000 vis=PRIVATE semFlags=0x0 semPriority=0 semMissedCount=0)) as user
05-15 17:27:45.346  1376  5727 E NotificationService: No Channel found for pkg=com.company.app, channelId=null, id=1337, tag=null, opPkg=com.company.app, callingUid=10514, userId=0, incomingUserId=0, notificationUid=10514, notification=Notification(channel=null shortcut=null contentView=null vibrate=null sound=null defaults=0x0 flags=0x10 color=0x00000000 vis=PRIVATE semFlags=0x0 semPriority=0 semMissedCount=0)
jkommeren commented 4 months ago

@jkommeren I'm happy for you, unfortunately it still doesn't work for me. Upon receiving a notification, logcat writes this:

05-15 17:27:45.340 21162 23707 I NotificationManager: com.company.app: notify(1337, null, Notification(channel=null shortcut=null contentView=null vibrate=null sound=null defaults=0x0 flags=0x10 color=0x00000000 vis=PRIVATE semFlags=0x0 semPriority=0 semMissedCount=0)) as user
05-15 17:27:45.346  1376  5727 E NotificationService: No Channel found for pkg=com.company.app, channelId=null, id=1337, tag=null, opPkg=com.company.app, callingUid=10514, userId=0, incomingUserId=0, notificationUid=10514, notification=Notification(channel=null shortcut=null contentView=null vibrate=null sound=null defaults=0x0 flags=0x10 color=0x00000000 vis=PRIVATE semFlags=0x0 semPriority=0 semMissedCount=0)

Here's the obvious question: are you creating your notification channel? I set up mine in the MainApplication.cs's OnCreate . (Which is also executed at startup of Android, and only once (?) but some people set it up in the Main activity)

After that you would need to inform the plugin what the channel id is that you just created.

FirebaseCloudMessagingImplementation.ChannelId = channelId;

Check https://github.com/coop-tim/maui-sample/blob/main/MauiSample/Platforms/Android/MainActivity.cs

For an example.

Just in case you didn't do it 😅

kalpasrl commented 4 months ago

I found the problem, the registration to the channel was done in the wrong place in the app. Thank you @jkommeren

jkommeren commented 4 months ago

I found the problem, the registration to the channel was done in the wrong place in the app. Thank you @jkommeren

You're welcome. Thanks for posting back!