我需要帮助Firebase for Unity。
当我在使用Google进行身份验证后尝试从数据库中编写(或读取)时,我得到Firebase Database error: Permission denied
(虽然在Facebook上运行正常)但重新启动应用后,它让我可以读写,不再抛出错误。
它最近开始发生,因为它在一周前工作正常。我的规则也正确设置(它第二次工作,这不是问题。它也适用于Facebook)。
我正在使用FirebaseAuth.DefaultInstance.StateChanged
,它甚至会在那里抛出错误。已填充FirebaseAuth.DefaultInstance.CurrentUser
变量 。我认为认证流程没有任何问题,因为它第二次启动应用程序时工作(Firebase已经登录,我只是通过google重新验证并调用SignInWithCredentials方法)由于某种原因。
我应该在身份验证后添加某种延迟吗?或者是别的什么?我错过了更新吗?
我已经阅读了其他问题,但没有一个有效。
MainMenu.cs
public IEnumerator CompleteGoogleLogin()
{
FirebaseAuth auth = FirebaseAuth.DefaultInstance;
Credential credential = GoogleAuthProvider.GetCredential(googleIdToken, googleAccessToken);
auth.SignInWithCredentialAsync(credential).ContinueWith(task =>
{
try
{
FirebaseUser newUser = task.Result;
Debug.LogError("[COMPLETE_GOOGLE_LOGIN] USER: " + JsonConvert.SerializeObject(FireDatabase.CurrentUser, Formatting.Indented));
var providerData = FireDatabase.ProviderData;
newUser.UpdateUserProfileAsync(new UserProfile()
{
DisplayName = newUser.DisplayName,
PhotoUrl = providerData.PhotoUrl
}).ContinueWith((t) =>
{
if (t.IsFaulted)
{
Debug.LogError("[COMPLETE_GOOGLE_LOGIN] EXCEPTIONS: " + JsonConvert.SerializeObject(t.Exception.InnerExceptions, Formatting.Indented));
Debug.LogError("[COMPLETE_GOOGLE_LOGIN] TASK IS FAULTED");
return;
}
if (t.IsCanceled)
{
Debug.LogError("[COMPLETE_GOOGLE_LOGIN] EXCEPTIONS: " + JsonConvert.SerializeObject(t.Exception.InnerExceptions, Formatting.Indented));
Debug.LogError("[COMPLETE_GOOGLE_LOGIN] TASK IS CANCELED");
return;
}
StartCoroutine(PostGoogleLogin());
});
}
catch (Exception e)
{
Debug.LogError("[COMPLETE_GOOGLE_LOGIN]: " + e.Message + " StackTrace: " + e.StackTrace);
if (e.InnerException != null)
Debug.LogError("[COMPLETE_GOOGLE_LOGIN] INNER_EXCEPTION: " + e.InnerException.Message + " StackTrace: " + e.InnerException.StackTrace);
}
});
}
private IEnumerator PostGoogleLogin()
{
yield return new WaitUntil(() => FireDatabase.IsLoggedIn);
// 09-14 22:54:02.208 28521 28742 W Unity : 01/02/0001 17:49:01 [Warn] RepoOperation: setValue at /users/XjGPJlZ45kPhVijKtxCOwA2xmHC2/name failed: DatabaseError: Permission denied
FireDatabase.UsersDatabase.Child(FireDatabase.CurrentUser.UserId).Child("name").SetValueAsync(FireDatabase.CurrentUser.DisplayName).ContinueWith((o) => {
if (o.IsFaulted)
{
// 09-14 22:54:02.276 28521 28545 E Unity : [POST_GOOGLE_LOGIN] EXCEPTIONS: [
// 09-14 22:54:02.276 28521 28545 E Unity : {
// 09-14 22:54:02.276 28521 28545 E Unity : "ClassName": "Firebase.Database.DatabaseException",
// 09-14 22:54:02.276 28521 28545 E Unity : "Message": "Firebase Database error: Permission denied",
// 09-14 22:54:02.276 28521 28545 E Unity : "Data": null,
// 09-14 22:54:02.276 28521 28545 E Unity : "InnerException": null,
// 09-14 22:54:02.276 28521 28545 E Unity : "HelpURL": null,
// 09-14 22:54:02.276 28521 28545 E Unity : "StackTraceString": null,
// 09-14 22:54:02.276 28521 28545 E Unity : "RemoteStackTraceString": null,
// 09-14 22:54:02.276 28521 28545 E Unity : "RemoteStackIndex": 0,
// 09-14 22:54:02.276 28521 28545 E Unity : "ExceptionMethod": null,
// 09-14 22:54:02.276 28521 28545 E Unity : "HResult": -2146233088,
// 09-14 22:54:02.276 28521 28545 E Unity : "Source": null
// 09-14 22:54:02.276 28521 28545 E Unity : }
// 09-14 22:54:02.276 28521 28545 E Unity : ]
Debug.LogError("[POST_GOOGLE_LOGIN] EXCEPTIONS: " + JsonConvert.SerializeObject(o.Exception.InnerExceptions, Formatting.Indented));
Debug.LogError("[POST_GOOGLE_LOGIN] TASK IS FAULTED");
return;
}
if (o.IsCanceled)
{
Debug.LogError("[POST_GOOGLE_LOGIN] EXCEPTIONS: " + JsonConvert.SerializeObject(o.Exception.InnerExceptions, Formatting.Indented));
Debug.LogError("[POST_GOOGLE_LOGIN] TASK IS CANCELED");
return;
}
StartCoroutine(DownloadProfilePicture(FireDatabase.ProviderData.PhotoUrl.AbsoluteUri + "?sz=" + (int) mainMenuProfilePicture.rectTransform.sizeDelta.x));
});
}
FireDatabase.cs
public static class FireDatabase
{
.....
public static FirebaseUser CurrentUser
{
get
{
return FirebaseAuth.DefaultInstance.CurrentUser;
}
}
public static bool IsLoggedIn
{
get
{
return CurrentUser != null && !string.IsNullOrEmpty(CurrentUser.UserId) && CurrentUser.ProviderData.Count() > 1;
}
}
public static IUserInfo ProviderData
{
get
{
if (!IsLoggedIn)
return null;
var providers = CurrentUser.ProviderData.GetEnumerator();
while (providers.MoveNext())
{
if (providers.Current.ProviderId == Provider.Google || providers.Current.ProviderId == Provider.Facebook)
return providers.Current;
}
return null;
}
}
public static DatabaseReference UsersDatabase
{
get
{
return FirebaseDatabase.DefaultInstance.RootReference.Child("users");
}
}
.....
static FireDatabase()
{
var serverDate = GetServerDate();
LeaderboardDatabase.Child(leaderboardType).Child(serverDate).KeepSynced(true);
FirebaseAuth.DefaultInstance.StateChanged += (s, e) =>
{
try
{
if (IsLoggedIn)
{
//09-14 22:32:43.870 25148 25409 W Unity : 01/02/0001 17:49:01 [Warn] SyncTree: Listen at /users/XjGPJlZ45kPhVijKtxCOwA2xmHC2 failed: DatabaseError: Permission denied
UsersDatabase.Child(CurrentUser.UserId).KeepSynced(true);
Debug.LogError("[FIRE_DATABASE] USER AUTH STATE CHANGED");
LeaderboardDatabase.Child(leaderboardType).Child(serverDate).ValueChanged += (sender, args) =>
{
Debug.LogError("LEADERBOARDS VALUE CHANGED");
GetRanking();
GetLeaderboards();
};
UsersDatabase.Child(CurrentUser.UserId).ValueChanged += (sender, args) =>
{
Debug.LogError("USER_PROFILE VALUE CHANGED");
GetPlayerProfile(); //<- This is being called when the StateChanged event is raised by firebase AFTER authentication
};
}
}
catch (Exception x)
{
Debug.LogError("[FIRE_DATABASE] " + x.Message + " StackTrace: " + x.StackTrace);
if (x.InnerException != null)
{
Debug.LogError("[FIRE_DATABASE] INNER EXCEPTION: " + x.InnerException.Message + " StackTrace: " + x.InnerException.StackTrace);
}
}
};
}
.....
public static void GetPlayerProfile()
{
if (CurrentUser != null)
//CurrentUser is not null, so it outputs the thing
Debug.LogError("[GET_PLAYER_PROFILE] USER: " + JsonConvert.SerializeObject(CurrentUser, Formatting.Indented));
else
return;
UsersDatabase.Child(CurrentUser.UserId).GetValueAsync().ContinueWith((t)=>
{
if (t.IsFaulted)
{
//09-14 22:32:44.088 25148 25178 E Unity : [GET_PLAYER_PROFILE] EXCEPTIONS: [
//09-14 22:32:44.088 25148 25178 E Unity : {
//09-14 22:32:44.088 25148 25178 E Unity : "ClassName": "Firebase.Database.DatabaseException",
//09-14 22:32:44.088 25148 25178 E Unity : "Message": "Firebase Database error: Permission denied",
//09-14 22:32:44.088 25148 25178 E Unity : "Data": null,
//09-14 22:32:44.088 25148 25178 E Unity : "InnerException": null,
//09-14 22:32:44.088 25148 25178 E Unity : "HelpURL": null,
//09-14 22:32:44.088 25148 25178 E Unity : "StackTraceString": null,
//09-14 22:32:44.088 25148 25178 E Unity : "RemoteStackTraceString": null,
//09-14 22:32:44.088 25148 25178 E Unity : "RemoteStackIndex": 0,
//09-14 22:32:44.088 25148 25178 E Unity : "ExceptionMethod": null,
//09-14 22:32:44.088 25148 25178 E Unity : "HResult": -2146233088,
//09-14 22:32:44.088 25148 25178 E Unity : "Source": null
//09-14 22:32:44.088 25148 25178 E Unity : }
//09-14 22:32:44.088 25148 25178 E Unity : ]
Debug.LogError("[GET_PLAYER_PROFILE] EXCEPTIONS: " + JsonConvert.SerializeObject(t.Exception.InnerExceptions, Formatting.Indented));
Debug.LogError("[GET_PLAYER_PROFILE] TASK IS FAULTED");
}
else if (t.IsCanceled)
{
Debug.LogError("[GET_PLAYER_PROFILE] EXCEPTIONS: " + JsonConvert.SerializeObject(t.Exception.InnerExceptions, Formatting.Indented));
Debug.LogError("[GET_PLAYER_PROFILE] TASK IS CANCELED");
}
else if (t.IsCompleted)
{
try
{
DataSnapshot snapshot = t.Result;
PlayerData pd = new PlayerData();
if (t.Result.ChildrenCount != 0)
JsonConvert.PopulateObject(snapshot.GetRawJsonValue(), pd);
Debug.LogError("[GET_PLAYER_PROFILE] TASK IS " + t.Result.GetType());
Debug.LogError("[GET_PLAYER_PROFILE] RAWJSON: " + snapshot.GetRawJsonValue());
ProfileChange?.Invoke(pd);
Debug.LogError("[GET_PLAYER_PROFILE] PROFILE_CHANGE " + (ProfileChange == null));
}
catch (Exception ex)
{
Debug.LogError("[GET_PLAYER_PROFILE] EXCEPTIONS: " + JsonConvert.SerializeObject(t.Exception.InnerExceptions, Formatting.Indented));
}
}
});
}
}
火葬规则:
{
"rules":
{
".read": "false",
".write": "false",
"users":{
".read":"false",
".write":"false",
"$user_id":{
".read":"auth!=null && $user_id == auth.uid",
".write":"auth!=null && $user_id == auth.uid"
}
}
}
}