xamarin / GooglePlayServicesComponents

Other
315 stars 146 forks source link

Firebase Messaging is not working in .NET Android #805

Closed fodorbalint closed 1 year ago

fodorbalint commented 1 year ago

Xamarin.Android Version (eg: 6.0):

net7.0-android

Operating System & Version (eg: Mac OSX 10.11):

Microsoft Windows 10 Home 10.0.19045

Google Play Services Version

Play Store Version on device: 37.7.19-29 [0] [PR] 567690537

Describe your Issue

I have recently migrated my app to .NET Adroid from Xamarin.Android where Firebase Messaging was working fine. Now I am not getting the token, and this message appears in the output window:

[FirebaseApp] Default FirebaseApp failed to initialize because no default options were found. This usually means that com.google.gms:google-services was not applied to your gradle project. [FirebaseInitProvider] FirebaseApp initialization unsuccessful

I have added the google-services.json to the project, I have extended the FirebaseMessagingService class. The AndroidManifest.xml also contains the code I used with Xamarin. (See samples below.)

Relevant information

AndroidApp2.csproj:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net7.0-android</TargetFramework>
    <SupportedOSPlatformVersion>21</SupportedOSPlatformVersion>
    <OutputType>Exe</OutputType>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
    <ApplicationId>com.companyname.AndroidApp2</ApplicationId>
    <ApplicationVersion>1</ApplicationVersion>
    <ApplicationDisplayVersion>1.0</ApplicationDisplayVersion>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Xamarin.Firebase.Messaging" Version="123.1.2.2" />
  </ItemGroup>
</Project>

Packages used:

<PackageReference Include="Xamarin.Firebase.Messaging" Version="123.1.2.2" />

Build settings (tools)

bundleassemblies=false aotassemblies=false androidaddkeepalives= androidaotmode=interpreter androidembedprofilers= androidenableprofiledaot= androiddextool=d8 androidlinktool= androidlinkresources= androidpackageformat=apk embedassembliesintoapk=false androidlinkmode=none androidlinkskip= androidsdkbuildtoolsversion=32.0.0 androidsdkpath=c:\program files (x86)\android\android-sdk\ androidndkpath= javasdkpath=c:\program files\microsoft\jdk-11.0.16.101-hotspot\ androidsequencepointsmode=none androidnetsdkversion=33.0.68 monosymbolarchive=false androiduselatestplatformsdk=false targetframeworkversion=v7.0 androidcreatepackageperabi= androidgeneratejnimarshalmethods=false os=windows_nt androidincludedebugsymbols=true androidpackagenamingpolicy=lowercasecrc64 _nugetassetstimestamp= typemapkind=strings-asm androidsupportedabis=arm64-v8a androidmanifestplaceholders=

or even better - links to the existing code:

https://github.com/fodorbalint/Firebase-Issue (For security reasons, I cannot disclose the contents of my google-services.json.) https://stackoverflow.com/questions/77220237/firebase-messaging-is-not-working-in-net-android

jonpryor commented 1 year ago

@fodorbalint: thank you for the repro at https://github.com/fodorbalint/Firebase-Issue, but… how do I use it?

For starters, it doesn't compile:

MyFirebaseMessagingService.cs(29,86): error CS1026: ) expected

which is simple enough to fix.

MainActivity.cs has FirebaseApp.InitializeApp(this) commented out, and I assume there is some form of configuration I need.

What do I need to do to fodorbalint/Firebase-Issue in order to observe the error you describe?

Thanks!

fodorbalint commented 1 year ago

That line was commented out, because it was not necessary in Xamarin, but in .NET I got an error with the old packages of Firebase that this line is needed. After inserting it, the error didn't go away though. The newest firebase package doesn't throw the error. Ultimately, I don't know if it is supposed to be there or not, but it doesn't make a difference anyway. To produce the error I described, connect a device and run the app. Then search for "firebase" in the output window.

jonpryor commented 1 year ago

@fodorbalint: fodorbalint/Firebase-Issue does not contain a google-services.json file. I realize you've stated:

I cannot disclose the contents of my google-services.json.

but that doesn't mean you can't provide a "blank" one, or otherwise use one.

More importantly, how are you including google-services.json? In Xamarin.Android, you would "normally" add it to your project with a Build action of @(GoogleServicesJson).

.NET Android does not have a default include rule for @(GoogleServicesJson). Consequently, it's identical to Xamarin.Android in this regard, which means you:

  1. (Still!) Need to have a @(PackageReference) to the Xamarin.GooglePlayServices.Basement NuGet package (as this provides the @(GoogleServicesJson) build action, and
  2. Set the build action for google-services.json to @(GoogleServicesJson).

You accomplish (1) and (2) by using <ItemGroup/>s:

<ItemGroup>
  <PackageReference Include="Xamarin.GooglePlayServices.Basement" Version="118.2.0.2" />
</ItemGroup>
<ItemGroup>
  <GoogleServicesJson Include="google-services.json" />
</ItemGroup>

When I "crib" a sample google-services.json, update AndroidApp2.csproj as described above, build, install, and run, I no longer see the Default FirebaseApp failed to initialize because no default options were found message.

diff --git a/AndroidApp2.csproj b/AndroidApp2.csproj
index 05d8a6d..b9fdc81 100644
--- a/AndroidApp2.csproj
+++ b/AndroidApp2.csproj
@@ -1,6 +1,6 @@
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
-    <TargetFramework>net7.0-android</TargetFramework>
+    <TargetFramework>net8.0-android</TargetFramework>
     <SupportedOSPlatformVersion>21</SupportedOSPlatformVersion>
     <OutputType>Exe</OutputType>
     <Nullable>enable</Nullable>
@@ -12,4 +12,10 @@
   <ItemGroup>
     <PackageReference Include="Xamarin.Firebase.Messaging" Version="123.1.2.2" />
   </ItemGroup>
-</Project>
\ No newline at end of file
+  <ItemGroup>
+    <PackageReference Include="Xamarin.GooglePlayServices.Basement" Version="118.2.0.2" />
+  </ItemGroup>
+  <ItemGroup>
+    <GoogleServicesJson Include="google-services.json" />
+  </ItemGroup>
+</Project>
diff --git a/MyFirebaseMessagingService.cs b/MyFirebaseMessagingService.cs
index a76d5e0..f3ce72e 100644
--- a/MyFirebaseMessagingService.cs
+++ b/MyFirebaseMessagingService.cs
@@ -26,7 +26,7 @@ namespace AndroidApp2

        public override void OnNewToken(string p0)
        {
-            System.Diagnostics.Debug.WriteLine(DateTime.UtcNow.ToString("OnNewToken");
+            System.Diagnostics.Debug.WriteLine(DateTime.UtcNow.ToString("OnNewToken"));

             base.OnNewToken(p0);
        }
diff --git a/google-services.json b/google-services.json
new file mode 100644
index 0000000..176bfee
--- /dev/null
+++ b/google-services.json
@@ -0,0 +1,50 @@
+{
+  "project_info": {
+    "project_number": "123456789",
+    "firebase_url": "https://YOUR-PROJECT-URL.firebaseio.com",
+    "project_id": "YOUR-PROJECT-ID",
+    "storage_bucket": "YOUR-PROJECT-URL.appspot.com"
+  },
+  "client": [
+    {
+      "client_info": {
+        "mobilesdk_app_id": "YOUR-APP-ID",
+        "android_client_info": {
+          "package_name": "balintfodor.locationconnection"
+        }
+      },
+      "oauth_client": [
+        {
+          "client_id": "YOUR-CLIENT-ID",
+          "client_type": 1,
+          "android_info": {
+            "package_name": "balintfodor.locationconnection",
+            "certificate_hash": "YOUR-CERT-HASH"
+          }
+        },
+        {
+          "client_id": "YOUR-CLIENT-ID",
+          "client_type": 3
+        }
+      ],
+      "api_key": [
+        {
+          "current_key": "YOUR-API-KEY"
+        }
+      ],
+      "services": {
+        "analytics_service": {
+          "status": 1
+        },
+        "appinvite_service": {
+          "status": 1,
+          "other_platform_oauth_client": []
+        },
+        "ads_service": {
+          "status": 2
+        }
+      }
+    },
+  ],
+  "configuration_version": "1"
+}
\ No newline at end of file

Surprisingly, that works?

10-11 21:38:00.446 14442 14442 I FirebaseApp: Device unlocked: initializing all Firebase APIs for app [DEFAULT]
10-11 21:38:00.449 14442 14442 I FirebaseInitProvider: FirebaseApp initialization successful

…which doesn't make any sense to me, as everything is GARBAGE in google-services.json, but there you go?

fodorbalint commented 1 year ago

Okay. I see that it works now. I just didn't remember having to set the build action of google-services.json in Xamarin. Actually, manually installing the Xamarin.GooglePlayServices.Basement package is not necessary now, it is listed among the dependencies of Firebase. Yes, Firebase will initialize with a dummy file, it just won't get the registration token.