'Firebase Realtime Database Rules not working after authentication and data sent
I am currently in the process of getting my project to run with Firebase. I've completed authentication through this script here.
using System.Collections.Generic;
using UnityEngine;
using GooglePlayGames;
using GooglePlayGames.BasicApi;
using UnityEngine.SocialPlatforms;
using System.Threading.Tasks;
using Firebase;
using Firebase.Auth;
public class FirebaseManager : MonoBehaviour
{
private string AuthCode;
private void Start()
{
// Initialize Play Games Configuration and Activate it.
PlayGamesClientConfiguration config = new PlayGamesClientConfiguration.Builder()
.RequestServerAuthCode(false)
.Build();
Debug.LogWarning("Config Built");
PlayGamesPlatform.InitializeInstance(config); Debug.LogWarning("Instance");
PlayGamesPlatform.Activate(); Debug.LogWarning("Activate");
Firebase.Auth.FirebaseAuth auth = Firebase.Auth.FirebaseAuth.DefaultInstance; // Sign In and Get a server auth code.
UnityEngine.Social.localUser.Authenticate((bool success) =>
{
if (!success)
{
Debug.LogError("SignInOnClick: Failed to Sign into Play Games Services.");
return;
}
string authCode = PlayGamesPlatform.Instance.GetServerAuthCode();
if (string.IsNullOrEmpty(authCode))
{
Debug.LogError("SignInOnClick: Signed into Play Games Services but failed to get the server auth code.");
return;
}
Debug.LogFormat("SignInOnClick: Auth code is: {0}", authCode); // Use Server Auth Code to make a credential
Firebase.Auth.Credential credential = Firebase.Auth.PlayGamesAuthProvider.GetCredential(authCode); // Sign In to Firebase with the credential
auth.SignInWithCredentialAsync(credential).ContinueWith(task => {
if (task.IsCanceled)
{
Debug.LogError("SignInOnClick was canceled.");
return;
}
if (task.IsFaulted)
{
Debug.LogError("SignInOnClick encountered an error: " + task.Exception);
return;
}
Firebase.Auth.FirebaseUser newUser = task.Result;
Debug.LogFormat("SignInOnClick: User signed in successfully: {0} ({1})", newUser.DisplayName, newUser.UserId);
});
});
}
}
Once i build this project onto Google Play and test it, it has the google UI pop up that shows my Google Play account name. Checking firebase authentication panel i can see my google play account populate the field with a UID.
I send some data to my database via REST API
using System.Collections.Generic;
using UnityEngine;
using Firebase.Database;
using Proyecto26;
using Firebase;
using Firebase.Auth;
using UnityEngine.UI;
using TMPro;
public class Database : MonoBehaviour
{
#region Instance
public static Database I;
public void GetInstance()
{
if(I == null)
{
I = this;
}
else
{
Destroy(I);
I = this;
}
}
private void Awake()
{
GetInstance();
}
#endregion
private string UID;
PlayerSaveData playerSaveData = new PlayerSaveData();
private void Start()
{
Debug.Log("Sending data");
LoadedData();
}
public void SavePlayerData()
{
UserID();
Debug.Log(UID);
RestClient.Put("https://-censored project linkrtdb.firebaseio.com/users" + UID + ".json", playerSaveData);
Debug.Log("Sent Data function complete");
}
public void LoadedData()
{
RestClient.Get<PlayerSaveData>("https://-censored project link-rtdb.firebaseio.com/users" + UID + ".json").Then(response =>
{
playerSaveData = response;
});
}
// UID //
public void UserID()
{
Firebase.Auth.FirebaseAuth auth = Firebase.Auth.FirebaseAuth.DefaultInstance;
Firebase.Auth.FirebaseUser user = auth.CurrentUser;
if (user != null)
{
string playerName = user.DisplayName;
// The user's Id, unique to the Firebase project.
// Do NOT use this value to authenticate with your backend server, if you
// have one; use User.TokenAsync() instead.
string uid = user.UserId;
Debug.LogWarning("Player UID: " + uid);
UID = uid;
}
else
{
UID = "No UID";
}
}
}
Once i check my data on the Database page on the Firebase Console on a live build via Google Play Market, the data only populates when i set the rules to test "Write = true and read = true for everyone"
However, once i add the rules from the documents that fit my situation
{
"rules": {
"users": {
"$uid": {
// Allow only authenticated content owners access to their data
".read": "auth != null && auth.uid == $uid",
".write": "auth != null && auth.uid == $uid"
}
}
}
}
The live application does not continue to write to the database.
My debug log on Logcat shoes the UID is spitting out the same exact UID that is authenticated on firebase.
I hate to be the guy that floods a forum with a question that i am sure has been asked a 100 times. I have been at this firebase thing for about 2 days, but i am throwing in the towel on this one. I can't find anything unique to my situation. With the little knowledge i have, i do feel that somehow the authentication is not sending with the way i structured my database.cs with REST. But i was assured this is the way i should go.
Any help would be greatly appreciated, much thanks to those that take the time! :D
Solution 1:[1]
It seems like your REST client is not passing the user credentials along with the request. The Firebase SDK passes this information with each connection/request, and you'll have to do the same here.
Have a look at the Firebase documentation on authorizing REST requests, specifically the section on authenticating with an ID token, which is probably easiest for you.
On the other hand, I'd recommend having a look using using the Firebase Realtime Database SDK instead of calling the REST API, as this will pass the required information automatically.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Frank van Puffelen |
