0

I am noob in Unity and I am trying to create an email and password authentication using Firebase. I am trying to create a scenario where if the client is offline (especially in an area where there is no connectivity), the client should be able to login offline. Is there any way to do this?

Below is the code I am using which I pulled from here.

using System;
using System.Collections.Generic;
using Firebase.Extensions;
using UnityEngine;
using UnityEngine.SceneManagement;

[CreateAssetMenu]
public class AuthManager : ScriptableObject
{
  // Firebase Authentication instance.
  protected Firebase.Auth.FirebaseAuth auth;

  // Firebase User keyed by Firebase Auth.
  protected Dictionary<string, Firebase.Auth.FirebaseUser> userByAuth =
    new Dictionary<string, Firebase.Auth.FirebaseUser>();

  // Flag to check if fetch token is in flight.
  private bool fetchingToken = false;

  // Handle initialization of the necessary firebase modules:
  public void InitializeFirebase()
  {
    Debug.Log("Setting up Firebase Auth");
    auth = Firebase.Auth.FirebaseAuth.DefaultInstance;
    auth.StateChanged += AuthStateChanged;
    auth.IdTokenChanged += IdTokenChanged;
    AuthStateChanged(this, null);
  }

  // Track state changes of the auth object.
  void AuthStateChanged(object sender, System.EventArgs eventArgs)
  {
    Firebase.Auth.FirebaseAuth senderAuth = sender as Firebase.Auth.FirebaseAuth;
    Firebase.Auth.FirebaseUser user = null;

    if (senderAuth != null) userByAuth.TryGetValue(senderAuth.App.Name, out user);
    if (senderAuth == auth && senderAuth.CurrentUser != user)
    {
      bool signedIn = user != senderAuth.CurrentUser && senderAuth.CurrentUser != null;
      if (!signedIn && user != null)
      {
        Debug.Log("Signed out " + user.UserId);
        SceneManager.LoadScene("SignInScene");
      }
      user = senderAuth.CurrentUser;
      userByAuth[senderAuth.App.Name] = user;
      if (signedIn)
      {
        Debug.Log("Signed in " + user.DisplayName);
        DisplayDetailedUserInfo(user, 1);
        SceneManager.LoadScene("MainScene");
      }
    }
    else
    {
      SceneManager.LoadScene("SignInScene");
    }
  }

  // Track ID token changes.
  void IdTokenChanged(object sender, System.EventArgs eventArgs)
  {
    Firebase.Auth.FirebaseAuth senderAuth = sender as Firebase.Auth.FirebaseAuth;
    if (senderAuth == auth && senderAuth.CurrentUser != null && !fetchingToken)
    {
      senderAuth.CurrentUser.TokenAsync(false).ContinueWithOnMainThread(
        task => Debug.Log(String.Format("Token[0:8] = {0}", task.Result.Substring(0, 8))));
    }
  }

  // Display a more detailed view of a FirebaseUser.
  protected void DisplayDetailedUserInfo(Firebase.Auth.FirebaseUser user, int indentLevel)
  {
    string indent = new String(' ', indentLevel * 2);
    DisplayUserInfo(user, indentLevel);
    Debug.Log(String.Format("{0}Anonymous: {1}", indent, user.IsAnonymous));
    Debug.Log(String.Format("{0}Email Verified: {1}", indent, user.IsEmailVerified));
    Debug.Log(String.Format("{0}Phone Number: {1}", indent, user.PhoneNumber));
    var providerDataList = new List<Firebase.Auth.IUserInfo>(user.ProviderData);
    var numberOfProviders = providerDataList.Count;
    if (numberOfProviders > 0)
    {
      for (int i = 0; i < numberOfProviders; ++i)
      {
        Debug.Log(String.Format("{0}Provider Data: {1}", indent, i));
        DisplayUserInfo(providerDataList[i], indentLevel + 2);
      }
    }
  }

  // Display user information.
  protected void DisplayUserInfo(Firebase.Auth.IUserInfo userInfo, int indentLevel)
  {
    string indent = new String(' ', indentLevel * 2);
    var userProperties = new Dictionary<string, string> {
        {"Display Name", userInfo.DisplayName},
        {"Email", userInfo.Email},
        {"Photo URL", userInfo.PhotoUrl != null ? userInfo.PhotoUrl.ToString() : null},
        {"Provider ID", userInfo.ProviderId},
        {"User ID", userInfo.UserId}
      };
    foreach (var property in userProperties)
    {
      if (!String.IsNullOrEmpty(property.Value))
      {
        Debug.Log(String.Format("{0}{1}: {2}", indent, property.Key, property.Value));
      }
    }
  }

  // Clean up auth state and auth.
  void OnDestroy()
  {
    auth.StateChanged -= AuthStateChanged;
    auth = null;
  }
}

1 Answer 1

1

There is no way to validate any credentials while the user is offline, so for most providers signing in while offline is not an option. The only built-in provider that can satisfy a signIn... call while offline, is the anonymous auth provider.

This is different when the user has already signed in in the past, and is restarting the app. In that scenario Firebase assumes the user is still signed in, will set the current user and fire the AuthStateListener event even while offline. Once the connection is reestablished it will re-validate the user credentials, to check for example if the account was suspended.

Sign up to request clarification or add additional context in comments.

4 Comments

Thank you. The scenario was after the user has already signed in previously.
any idea how long a Firebase token takes to expire after an email and password auth login?
Firebase's ID tokens are valid for an hour. The SDK automatically generates a new ID token after about 55 minutes.
Can the expiration extended to more than an hour?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.