I have recently faced a problem with my Unity app.
I have added Facebook Auth, everything seemed to work fine on the first login and using cached logins (SessionToken)
The problem only occurs when I delete and re-install the app and log in with Facebook again, I get the ‘currentSpins’ value set to 10 which is default for new players even tho my account had a different value on Firebase Firestore.
As soon as I login on a freshly installed app, I get the currentSpins key deleted from Firestore and added again as 10.
This only happens when I re-install the app, otherwise cached logins work fine and retreive the correct value from the Firestore database.
using UnityEngine;
using Facebook.Unity;
using Firebase.Auth;
using Firebase.Firestore;
using System.Collections.Generic;
using UnityEngine.SceneManagement;
using Firebase;
public class AuthenticationFacebook : MonoBehaviour
{
private bool isLoggingIn = false;
private void Start()
{
if (!FB.IsInitialized)
{
FB.Init(OnFacebookInitialized);
}
else
{
OnFacebookInitialized();
}
}
private void OnFacebookInitialized()
{
if (FB.IsInitialized)
{
FB.ActivateApp();
CheckCachedLogin();
}
else
{
Debug.LogError("Failed to initialize Facebook SDK");
}
}
private void CheckCachedLogin()
{
if (FB.IsLoggedIn)
{
ContinueWithCachedLogin();
}
else
{
string cachedAccessToken = PlayerPrefs.GetString("FacebookAccessToken");
if (!string.IsNullOrEmpty(cachedAccessToken))
{
AccessToken.CurrentAccessToken = new AccessToken(cachedAccessToken, AccessToken.CurrentAccessToken.UserId, AccessToken.CurrentAccessToken.ExpirationTime, null, null, null);
ContinueWithCachedLogin();
}
}
}
public void ContinueWithCachedLogin()
{
FirebaseUser user = FirebaseAuth.DefaultInstance.CurrentUser;
if (user != null)
{
GoToWheelScene();
}
else
{
SignInWithFacebook();
}
}
public void SignInWithFacebook()
{
if (!isLoggingIn)
{
isLoggingIn = true;
var perms = new List<string>() { "public_profile", "email" };
FB.LogInWithReadPermissions(perms, OnFacebookLoggedIn);
}
}
private void OnFacebookLoggedIn(ILoginResult result)
{
isLoggingIn = false;
if (FB.IsLoggedIn)
{
AccessToken accessToken = AccessToken.CurrentAccessToken;
string facebookAccessToken = accessToken.TokenString;
PlayerPrefs.SetString("FacebookAccessToken", facebookAccessToken);
FirebaseAuth auth = FirebaseAuth.DefaultInstance;
FirebaseUser user = auth.CurrentUser;
FirebaseFirestore firestore = FirebaseFirestore.GetInstance(FirebaseApp.DefaultInstance);
firestore.Settings.PersistenceEnabled = false;
if (user == null)
{
Credential credential = FacebookAuthProvider.GetCredential(facebookAccessToken);
auth.SignInWithCredentialAsync(credential).ContinueWith(task =>
{
if (task.IsCanceled)
{
Debug.LogError("SignInWithCredentialAsync was canceled.");
return;
}
if (task.IsFaulted)
{
Debug.LogError("SignInWithCredentialAsync encountered an error: " + task.Exception);
return;
}
FirebaseUser newUser = task.Result;
Debug.Log("User signed in successfully with Facebook! Player ID: " + newUser.UserId);
// Store user data in Firestore for new players
FirebaseFirestore db = FirebaseFirestore.DefaultInstance;
DocumentReference docRef = db.Collection("players").Document(newUser.UserId);
var dataToSave = new Dictionary<string, object>
{
{ "email", newUser.Email },
{ "name", newUser.DisplayName },
{ "facebookId", accessToken.UserId } // Store the Facebook User ID
};
docRef.SetAsync(dataToSave).ContinueWith(setTask =>
{
if (setTask.IsCompleted)
{
Debug.Log("Player document created and basic data saved in Firestore.");
// Link Facebook credential with Firebase Auth UID
newUser.LinkWithCredentialAsync(credential).ContinueWith(linkTask =>
{
if (linkTask.IsCompleted)
{
Debug.Log("Facebook credential linked with Firebase UID.");
}
GoToWheelScene();
});
}
else if (setTask.IsFaulted)
{
Debug.LogError("Failed to save player data: " + setTask.Exception);
}
});
});
}
else
{
Debug.Log("User is already logged in. Player ID: " + user.UserId);
GoToWheelScene();
}
}
else
{
Debug.LogError("Facebook login failed");
}
}
private void GoToWheelScene()
{
if (!isLoggingIn)
{
SceneManager.LoadScene("2. Wheel");
}
}
}
using UnityEngine;
using TMPro;
using Firebase;
using Firebase.Firestore;
using System;
using System.Threading.Tasks;
using System.Collections.Generic;
using Firebase.Auth;
public class SpinsCounter : MonoBehaviour
{
public int startingSpins = 10;
private int currentSpins;
private bool cloudDataLoaded = false;
public Transform spinButton;
public Transform rewardButton;
public TMP_Text spinsText;
private FirebaseFirestore db;
private string currentUserId;
private FirebaseAuth auth;
async void Awake()
{
await InitializeFirebase();
await LoadDataFromFirestore();
Debug.Log("Data loaded: " + cloudDataLoaded);
UpdateSpinUI();
}
async Task InitializeFirebase()
{
var dependencyStatus = await FirebaseApp.CheckAndFixDependenciesAsync();
if (dependencyStatus == DependencyStatus.Available)
{
Debug.Log("Firebase dependencies available.");
db = FirebaseFirestore.DefaultInstance;
auth = FirebaseAuth.DefaultInstance;
}
else
{
Debug.LogError("Could not resolve all Firebase dependencies: " + dependencyStatus);
}
}
async Task LoadDataFromFirestore()
{
Debug.Log("Loading data from Firestore...");
FirebaseUser user = auth.CurrentUser;
if (user != null)
{
Debug.Log("User found: " + user.UserId);
currentUserId = user.UserId;
DocumentReference docRef = db.Collection("players").Document(currentUserId);
var task = docRef.GetSnapshotAsync();
await task;
if (task.IsFaulted || task.IsCanceled)
{
Debug.LogError("Failed to load data from Firestore.");
cloudDataLoaded = false;
return;
}
DocumentSnapshot snapshot = task.Result;
if (snapshot != null && snapshot.Exists)
{
Dictionary<string, object> data = snapshot.ToDictionary();
if (data.TryGetValue("currentSpins", out object spinsItem))
{
currentSpins = Convert.ToInt32(spinsItem);
}
else
{
currentSpins = startingSpins;
}
cloudDataLoaded = true;
Debug.Log("Data loaded successfully.");
}
else
{
Debug.LogWarning("No data found in Firestore for user: " + currentUserId);
currentSpins = startingSpins;
cloudDataLoaded = true; // Set cloudDataLoaded to true even when no data is found
}
}
else
{
Debug.LogError("No user logged in.");
cloudDataLoaded = false;
}
}
async Task SaveDataToFirestore()
{
if (cloudDataLoaded)
{
DocumentReference docRef = db.Collection("players").Document(currentUserId);
var dataToSave = new Dictionary<string, object>
{
{ "currentSpins", currentSpins }
};
await docRef.SetAsync(dataToSave, SetOptions.MergeAll);
Debug.Log("Data saved to Firestore.");
}
}
public void OnApplicationQuit()
{
_ = SaveDataToFirestore();
Debug.Log("Application quit. Data saved to Firestore.");
}
public void OnSpinButtonClick()
{
if (cloudDataLoaded)
{
if (currentSpins > 0)
{
currentSpins--;
UpdateSpinUI();
_ = SaveDataToFirestore();
}
}
}
public void ExtraSpinWin()
{
if (cloudDataLoaded)
{
currentSpins += 3;
UpdateSpinUI();
_ = SaveDataToFirestore();
}
}
public void UpdateSpinUI()
{
spinsText.text = "Spins: " + currentSpins.ToString();
spinButton.gameObject.SetActive(cloudDataLoaded && currentSpins > 0);
}
}