Search code examples
androidfirebaseunity-game-enginegoogle-play-servicesgoogle-signin

Unity Android Firebase Google Auth can't find google-services.json


I am trying to setup a Google sign-in auth in Unity 2022.3.1f1 for Android. I already have a firebase database set up and running fine.

I installed these packages :

  • FirebaseAnalytics
  • FirebaseAuth
  • FirebaseDatabase

from here : https://firebase.google.com/docs/auth/unity/google-signin and the Google Sign-In plugin from here : https://github.com/googlesamples/google-signin-unity/releases (1.0.4), so the latest versions of the packages.

Questions : How can I get the google auth working ? Why isn't my google-services.json file found on my phone in Assets/StreamingAssets, Assets/, ... Why is the firebase (realtime) database working without the google-services.json but not the Auth ?

Problems and what i have tried :

My 1st problem was that the google-services.json (placed in the Assets folder) wasn't found in the editor or phone. I copied it and placed it in Assets/StreamingAssets, and was then found by the editor (making the firebase database work).

My problem now is that the google-services.json is found in the editor but not on my phone. This is the log error :

07-01 11:49:38.349: E/Unity(21303): Failed to read Firebase options from the app's resources. Either make sure google-services.json is included in your build or specify options explicitly.

So I explicitly specified the options like this :

Firebase.AppOptions options = new Firebase.AppOptions();
                options.ApiKey = "SameApiKeyInGoogleServicesJson";
                options.AppId = "SameAppIdyInGoogleServicesJson";
                options.ProjectId = "SameProjectIdInGoogleServicesJson";
                options.StorageBucket = "SameStorageBucketInGoogleServicesJson";
                options.DatabaseUrl = new System.Uri("SameDatabaseUrlInGoogleServicesJson");

                app = Firebase.FirebaseApp.Create(options);

The database now works on my phone, the Sign-In page pops up but after choosing an account I get still get the error and more.

The log :

07-01 12:19:41.006: I/Unity(28431): Google checked dependencies
07-01 12:19:41.006: I/Unity(28431): LoginManager:<Start>b__7_0(Task`1)
07-01 12:19:41.006: I/Unity(28431): System.Threading.Tasks.Task:Execute()
07-01 12:19:41.006: I/Unity(28431): System.Threading.ExecutionContext:RunInternal(ExecutionContext, ContextCallback, Object, Boolean)
07-01 12:19:41.006: I/Unity(28431): System.Threading.Tasks.Task:ExecuteWithThreadLocal(Task&)
07-01 12:19:41.006: I/Unity(28431): System.Threading.Tasks.Task:ExecuteEntry(Boolean)
07-01 12:19:41.006: I/Unity(28431): System.Threading.ThreadPoolWorkQueue:Dispatch()
07-01 12:19:41.006: I/Unity(28431): Loading default instances
07-01 12:19:41.006: I/Unity(28431): LoginManager:<Start>b__7_0(Task`1)
07-01 12:19:41.006: I/Unity(28431): System.Threading.Tasks.Task:Execute()
07-01 12:19:41.006: I/Unity(28431): System.Threading.ExecutionContext:RunInternal(ExecutionContext, ContextCallback, Object, Boolean)
07-01 12:19:41.006: I/Unity(28431): System.Threading.Tasks.Task:ExecuteWithThreadLocal(Task&)
07-01 12:19:41.006: I/Unity(28431): System.Threading.Tasks.Task:ExecuteEntry(Boolean)
07-01 12:19:41.006: I/Unity(28431): System.Threading.ThreadPoolWorkQueue:Dispatch()
07-01 12:19:41.109: E/Unity(28431): Failed to read Firebase options from the app's resources. Either make sure google-services.json is included in your build or specify options explicitly.
07-01 12:19:41.109: E/Unity(28431): Firebase.AppUtilPINVOKE:PollCallbacks()
07-01 12:19:41.109: E/Unity(28431): Firebase.AppUtil:PollCallbacks()
07-01 12:19:41.109: E/Unity(28431): Firebase.Platform.FirebaseHandler:Update()
07-01 12:19:41.186: I/Unity(28431): Loaded default instances
07-01 12:19:41.186: I/Unity(28431): LoginManager:<Start>b__7_0(Task`1)
07-01 12:19:41.186: I/Unity(28431): System.Threading.Tasks.Task:Execute()
07-01 12:19:41.186: I/Unity(28431): System.Threading.ExecutionContext:RunInternal(ExecutionContext, ContextCallback, Object, Boolean)
07-01 12:19:41.186: I/Unity(28431): System.Threading.Tasks.Task:ExecuteWithThreadLocal(Task&)
07-01 12:19:41.186: I/Unity(28431): System.Threading.Tasks.Task:ExecuteEntry(Boolean)
07-01 12:19:41.186: I/Unity(28431): System.Threading.ThreadPoolWorkQueue:Dispatch()
07-01 12:19:41.220: I/Unity(28431): SAVED TO DATABASE
07-01 12:19:41.220: I/Unity(28431): LoginManager:<Start>b__7_0(Task`1)
07-01 12:19:41.220: I/Unity(28431): System.Threading.Tasks.Task:Execute()
07-01 12:19:41.220: I/Unity(28431): System.Threading.ExecutionContext:RunInternal(ExecutionContext, ContextCallback, Object, Boolean)
07-01 12:19:41.220: I/Unity(28431): System.Threading.Tasks.Task:ExecuteWithThreadLocal(Task&)
07-01 12:19:41.220: I/Unity(28431): System.Threading.Tasks.Task:ExecuteEntry(Boolean)
07-01 12:19:41.220: I/Unity(28431): System.Threading.ThreadPoolWorkQueue:Dispatch()
07-01 12:19:41.221: I/Unity(28431): Signing in google
07-01 12:19:41.221: I/Unity(28431): LoginManager:GoogleSignInClick()
07-01 12:19:41.221: I/Unity(28431): System.Threading.Tasks.Task:Execute()
07-01 12:19:41.221: I/Unity(28431): System.Threading.ExecutionContext:RunInternal(ExecutionContext, ContextCallback, Object, Boolean)
07-01 12:19:41.221: I/Unity(28431): System.Threading.Tasks.Task:ExecuteWithThreadLocal(Task&)
07-01 12:19:41.221: I/Unity(28431): System.Threading.Tasks.Task:ExecuteEntry(Boolean)
07-01 12:19:41.221: I/Unity(28431): System.Threading.ThreadPoolWorkQueue:Dispatch()
07-01 12:19:49.716: E/Unity(28431): g_methods_cached
07-01 12:19:49.716: E/Unity(28431): Firebase.AppUtilPINVOKE:PollCallbacks()
07-01 12:19:49.716: E/Unity(28431): Firebase.AppUtil:PollCallbacks()
07-01 12:19:49.716: E/Unity(28431): Firebase.Platform.FirebaseHandler:Update()

First error :

07-01 12:19:41.109: E/Unity(28431): Failed to read Firebase options from the app's resources. Either make sure google-services.json is included in your build or specify options explicitly.
07-01 12:19:41.109: E/Unity(28431): Firebase.AppUtilPINVOKE:PollCallbacks()
07-01 12:19:41.109: E/Unity(28431): Firebase.AppUtil:PollCallbacks()
07-01 12:19:41.109: E/Unity(28431): Firebase.Platform.FirebaseHandler:Update()

Second error :

07-01 12:19:49.716: E/Unity(28431): g_methods_cached
07-01 12:19:49.716: E/Unity(28431): Firebase.AppUtilPINVOKE:PollCallbacks()
07-01 12:19:49.716: E/Unity(28431): Firebase.AppUtil:PollCallbacks()
07-01 12:19:49.716: E/Unity(28431): Firebase.Platform.FirebaseHandler:Update()

This is the code :

using System.Collections.Generic;
using UnityEngine;
using System.Threading.Tasks;
using TMPro;
using Firebase;
using Google;
using Firebase.Extensions;
using Firebase.Database;
using Firebase.Auth;
using System;

public class LoginManager : MonoBehaviour
{

    public TextMeshProUGUI text;

    FirebaseApp app;
    Firebase.Auth.FirebaseAuth auth;
    private GoogleSignInConfiguration configuration;
    Firebase.Auth.FirebaseUser user;

    Statistics stats;
    DatabaseReference mDatabaseRef;


    // Start is called before the first frame update
    void Start()
    {
        configuration = new GoogleSignInConfiguration();
        configuration.WebClientId = "SameInGoogleServicesJson";
        configuration.RequestIdToken = true;
        configuration.RequestEmail = true;
        configuration.RequestProfile = true;

        FirebaseApp.CheckAndFixDependenciesAsync().ContinueWith(task => {
            var dependencyStatus = task.Result;
            if (dependencyStatus == Firebase.DependencyStatus.Available)
            {
                // Create and hold a reference to your FirebaseApp,
                // where app is a Firebase.FirebaseApp property of your application class.
                Debug.Log("Google checked dependencies");
                Debug.Log("Loading default instances");

                Firebase.AppOptions options = new Firebase.AppOptions();
                options.ApiKey = "SameApiKeyInGoogleServicesJson";
                options.AppId = "SameAppIdyInGoogleServicesJson";
                options.ProjectId = "SameProjectIdInGoogleServicesJson";
                options.StorageBucket = "SameStorageBucketInGoogleServicesJson";
                options.DatabaseUrl = new System.Uri("SameDatabaseUrlInGoogleServicesJson");

                app = Firebase.FirebaseApp.Create(options);
                Debug.Log("Loaded default instances");

                //TestDatabase
                mDatabaseRef = FirebaseDatabase.DefaultInstance.RootReference;
                writeNewStats("userId");

                //Login
                GoogleSignInClick();

            }
            else
            {
                UnityEngine.Debug.LogError(System.String.Format(
                  "Could not resolve all Firebase dependencies: {0}", dependencyStatus));
                // Firebase Unity SDK is not safe to use here.
            }
        });

    }

    void GoogleSignInClick()
    {
        Debug.Log("Signing in google");

        GoogleSignIn.Configuration = configuration;
        GoogleSignIn.Configuration.UseGameSignIn = false;
        GoogleSignIn.Configuration.RequestIdToken = true;
        GoogleSignIn.Configuration.RequestEmail = true;

        GoogleSignIn.DefaultInstance.SignIn().ContinueWith(OnGoogleAuthenticatedFinished);
    }

    void OnGoogleAuthenticatedFinished(Task<GoogleSignInUser> task)
    {

        if (task.IsFaulted)
        {
            Debug.LogError("Google Sign In : Fault");
            Debug.Log(task.Exception.ToString());
        }
        else if (task.IsCanceled)
        {
            Debug.LogError("Google Sign In : Canceled");
        }
        else
        {
            Firebase.Auth.Credential credential = Firebase.Auth.GoogleAuthProvider.GetCredential(task.Result.IdToken, null);
            Debug.LogError("Create credentials");

            auth.SignInWithCredentialAsync(credential).ContinueWithOnMainThread(task =>
            {

                if (task.IsCanceled)
                {
                    Debug.LogError("SignInWithCredential was canceled");
                    return;
                }

                if (task.IsFaulted)
                {
                    Debug.LogError("SignInWithCredential encountered an error " + task.Exception);
                    return;
                }

                user = auth.CurrentUser;
                Debug.Log("User name : " + user.DisplayName);
                Debug.Log("User email : " + user.Email);
            });
        }

    }




    private void writeNewStats(string userId)
    {
        stats = new Statistics();
        string json = JsonUtility.ToJson(stats);

        mDatabaseRef.Child("users").Child(userId).SetRawJsonValueAsync(json);

        Debug.Log("SAVED TO DATABASE");
    }
}

I tried renaming folders with .androidlib, changing the google-services.json location, deleting the packages and redownloading them making sure they don't overite other packages, implementing the code differently, but the best I found is what I have here.

I hope I have given enough information, thanks for the future help !


Solution

  • Ok so I've managed to make it work but not with the latest updates. I exported an older project's packages (the folders :

    1. EditorDefaultResources
    2. ExternalDependencyManager
    3. Firebase
    4. GoogleSignIn
    5. Parse
    6. Plugins

    )

    which used the v9.2.0 SDK (auth, app, database, analytics) and the same GoogleSign-In package v1.0.4 with the 2021.3.6f1 version of Unity.

    I put my google-services.json in StreamingAssets/ (But it was also found in Assets/) and changed manually the \Assets\Plugins\Android\FirebaseApp.androidlib\res\values\google-services.xml with the corresponding google-services.json values.

    I don't know what the problem was with the newer versions but this seems to work.