Skip to content

Commit c633e18

Browse files
authored
Merge pull request #2 from Slympp/master
✨ Anonymous SignIn, handle token refresh & Fixed BeginListeningServerEvents
2 parents 06540f3 + 80c99c2 commit c633e18

File tree

3 files changed

+128
-82
lines changed

3 files changed

+128
-82
lines changed

Assets/FirebaseREST/Auth/FirebaseAuth.cs

+24-29
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ public class FirebaseAuth : MonoBehaviour
1212
{
1313
readonly string EMAIL_AUTH_URL = "https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyPassword?key=" + FirebaseSettings.WEB_API;
1414
readonly string CUSTOM_TOKEN_AUTH_URL = "https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyCustomToken?key=" + FirebaseSettings.WEB_API;
15+
readonly string ANONYMOUS_AUTH_URL = "https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=" + FirebaseSettings.WEB_API;
1516
readonly string REFRESH_TOKEN_URL = "https://securetoken.googleapis.com/v1/token?key=" + FirebaseSettings.WEB_API;
1617
readonly string USER_INFO_URL = "https://www.googleapis.com/identitytoolkit/v3/relyingparty/getAccountInfo?key=" + FirebaseSettings.WEB_API;
1718
TokenData tokenData;
@@ -64,36 +65,27 @@ void OnDestroy()
6465
{
6566
applicationIsQuitting = true;
6667
}
68+
69+
public bool IsSignedIn => tokenData != null;
6770

68-
public string AccessToken
69-
{
70-
get
71-
{
72-
if (tokenData == null)
73-
return null;
74-
return tokenData.idToken;
75-
}
76-
}
77-
78-
public bool IsSignedIn
79-
{
80-
get
81-
{
82-
return tokenData != null;
83-
}
71+
public void GetAccessToken(Action<string> onComplete) {
72+
if (tokenData == null)
73+
onComplete?.Invoke(null);
74+
else if (IsTokenExpired)
75+
RefreshAccessToken(10, response => onComplete(response.data.IdToken));
76+
else
77+
onComplete?.Invoke(tokenData.IdToken);
8478
}
8579

86-
void Awake()
87-
{
80+
private bool IsTokenExpired => DateTime.Now - tokenData.RefreshedAt > TimeSpan.FromSeconds(double.Parse(tokenData.ExpiresIn));
8881

89-
}
9082

9183
public void FetchUserInfo(int timeout, Action<Response<List<UserData>>> OnComplete)
9284
{
9385
if (tokenData == null)
9486
throw new Exception("User has not logged in");
9587
UnityWebRequestAsyncOperation op = StartRequest(USER_INFO_URL, "POST", new Dictionary<string, object>(){
96-
{"idToken",tokenData.idToken}
88+
{"idToken",tokenData.IdToken}
9789
}, timeout);
9890
op.completed += ((ao) => HandleFirebaseResponse(op, (res) =>
9991
{
@@ -148,17 +140,15 @@ public void RefreshAccessToken(int timeout, Action<Response<TokenData>> OnComple
148140
if (tokenData == null)
149141
throw new Exception("User has not logged in");
150142
UnityWebRequestAsyncOperation op = StartRequest(REFRESH_TOKEN_URL, "POST", new Dictionary<string, object>(){
151-
{"grant_type","refresh_token"},{"refresh_token",tokenData.refreshToken}
143+
{"grant_type","refresh_token"},{"refresh_token",tokenData.RefreshToken}
152144
}, timeout);
153145
op.completed += ((ao) => HandleFirebaseResponse(op, (res) =>
154146
{
155147
if (res.success)
156148
{
157149
Dictionary<string, object> dataMap = Json.Deserialize(op.webRequest.downloadHandler.text) as Dictionary<string, object>;
158-
this.tokenData = new TokenData();
159-
tokenData.expiresIn = dataMap["expires_in"].ToString();
160-
tokenData.idToken = dataMap["id_token"].ToString();
161-
tokenData.refreshToken = dataMap["refresh_token"].ToString();
150+
tokenData = new TokenData(dataMap["id_token"].ToString(), dataMap["refresh_token"].ToString(),
151+
dataMap["expires_in"].ToString(), DateTime.Now);
162152
if (OnComplete != null)
163153
OnComplete(new Response<TokenData>("success", true, (int)op.webRequest.responseCode, tokenData));
164154
}
@@ -185,6 +175,14 @@ public void SignInWithEmail(string email, string password, int timeout, Action<R
185175
}, timeout);
186176
op.completed += ((ao) => HandleFirebaseSignInResponse(op, OnComplete));
187177
}
178+
179+
public void SignInAnonymously(int timeout, Action<Response<TokenData>> OnComplete)
180+
{
181+
UnityWebRequestAsyncOperation op = StartRequest(ANONYMOUS_AUTH_URL, "POST", new Dictionary<string, object>(){
182+
{"returnSecureToken",true}
183+
}, timeout);
184+
op.completed += ((ao) => HandleFirebaseSignInResponse(op, OnComplete));
185+
}
188186

189187
UnityWebRequestAsyncOperation StartRequest(string url, string requestMethod, Dictionary<string, object> data, int timeout)
190188
{
@@ -216,10 +214,7 @@ void HandleFirebaseSignInResponse(UnityWebRequestAsyncOperation webReqOp, Action
216214
if (OnComplete != null)
217215
{
218216
Dictionary<string, object> dataMap = Json.Deserialize(webReqOp.webRequest.downloadHandler.text) as Dictionary<string, object>;
219-
this.tokenData = new TokenData();
220-
tokenData.expiresIn = dataMap["expiresIn"].ToString();
221-
tokenData.idToken = dataMap["idToken"].ToString();
222-
tokenData.refreshToken = dataMap["refreshToken"].ToString();
217+
this.tokenData = new TokenData(dataMap["idToken"].ToString(), dataMap["refreshToken"].ToString(), dataMap["expiresIn"].ToString(), DateTime.Now);
223218
OnComplete(new Response<TokenData>("success", true, (int)webReqOp.webRequest.responseCode, tokenData));
224219
}
225220
}
+13-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,19 @@
1+
using System;
2+
13
namespace FirebaseREST
24
{
35
public class TokenData
46
{
5-
public string idToken;
6-
public string refreshToken;
7-
public string expiresIn;
7+
public string IdToken { get; }
8+
public string RefreshToken { get; }
9+
public string ExpiresIn { get; }
10+
public DateTime RefreshedAt { get; }
11+
12+
public TokenData(string idToken, string refreshToken, string expiresIn, DateTime refreshedAt) {
13+
IdToken = idToken;
14+
RefreshToken = refreshToken;
15+
ExpiresIn = expiresIn;
16+
RefreshedAt = refreshedAt;
17+
}
818
}
919
}

Assets/FirebaseREST/Database/DatabaseReference.cs

+91-50
Original file line numberDiff line numberDiff line change
@@ -52,28 +52,40 @@ void BeginListeningServerEvents()
5252
#if UNITY_WEBGL && !UNITY_EDITOR
5353
if (esGL != null) return;
5454
string url = this.ReferenceUrl;
55-
bool withCredential = false;
56-
if (FirebaseAuth.Instance.IsSignedIn)
57-
{
58-
url = url + "?auth=" + FirebaseAuth.Instance.AccessToken;
59-
withCredential = true;
55+
if (FirebaseAuth.Instance.IsSignedIn) {
56+
FirebaseAuth.Instance.GetAccessToken((accessToken) => {
57+
url = url + "?auth=" + accessToken;
58+
esGL = new FirebaseDatabase.FirebaseEventSourceWebGL(url, true, null,
59+
OnEventSourceMessageReceived, OnEventSourceError);
60+
});
61+
} else {
62+
esGL = new FirebaseDatabase.FirebaseEventSourceWebGL(url, false, null,
63+
OnEventSourceMessageReceived, OnEventSourceError);
6064
}
61-
esGL = new FirebaseDatabase.FirebaseEventSourceWebGL(url, withCredential, null,
62-
OnEventSourceMessageReceived, OnEventSourceError);
65+
6366
#else
6467
if (webReq != null) return;
6568
string url = this.ReferenceUrl;
66-
if (FirebaseAuth.Instance.IsSignedIn)
67-
url = url + "?auth=" + FirebaseAuth.Instance.AccessToken;
68-
webReq = new UnityWebRequest(url);
69-
webReq.SetRequestHeader("Accept", "text/event-stream");
70-
webReq.SetRequestHeader("Cache-Control", "no-cache");
71-
FirebaseServerEventsDownloadHandler downloadHandler = new FirebaseServerEventsDownloadHandler();
72-
downloadHandler.DataReceived += OnDataReceived;
73-
webReq.downloadHandler = downloadHandler;
74-
webReq.disposeDownloadHandlerOnDispose = true;
75-
UnityWebRequestAsyncOperation webReqAO = webReq.SendWebRequest();
76-
webReqAO.completed += ((ao) => OnStopListening(webReqAO));
69+
70+
Action sendRequest = () => {
71+
webReq = new UnityWebRequest(url);
72+
webReq.SetRequestHeader("Accept", "text/event-stream");
73+
webReq.SetRequestHeader("Cache-Control", "no-cache");
74+
FirebaseServerEventsDownloadHandler downloadHandler = new FirebaseServerEventsDownloadHandler();
75+
downloadHandler.DataReceived += OnDataReceived;
76+
webReq.downloadHandler = downloadHandler;
77+
webReq.disposeDownloadHandlerOnDispose = true;
78+
UnityWebRequestAsyncOperation webReqAO = webReq.SendWebRequest();
79+
webReqAO.completed += ((ao) => OnStopListening(webReqAO));
80+
};
81+
82+
if (FirebaseAuth.Instance.IsSignedIn) {
83+
FirebaseAuth.Instance.GetAccessToken(accessToken => {
84+
url = url + "?auth=" + accessToken;
85+
sendRequest();
86+
});
87+
} else
88+
sendRequest();
7789
#endif
7890
}
7991

@@ -498,17 +510,22 @@ public override void GetValueAsync(int timeout, Action<Response<DataSnapshot>> O
498510
webReq.downloadHandler = new DownloadHandlerBuffer();
499511
webReq.timeout = timeout;
500512

501-
if (FirebaseAuth.Instance.IsSignedIn)
502-
{
503-
string sign = query == null ? "?" : "&";
504-
webReq.url = webReq.url + sign + "auth=" + FirebaseAuth.Instance.AccessToken;
513+
Action sendRequest = () => {
514+
var op = webReq.SendWebRequest();
515+
op.completed += (ao) => HandleFirebaseDatabaseResponse(op, res => {
516+
OnComplete?.Invoke(new Response<DataSnapshot>(res.message, res.success, res.code, new FirebaseDataSnapshot(this, Json.Deserialize(res.data))));
517+
});
518+
};
519+
520+
if (FirebaseAuth.Instance.IsSignedIn) {
521+
FirebaseAuth.Instance.GetAccessToken(accessToken => {
522+
string sign = query == null ? "?" : "&";
523+
webReq.url = webReq.url + sign + "auth=" + accessToken;
524+
sendRequest();
525+
});
526+
} else {
527+
sendRequest();
505528
}
506-
UnityWebRequestAsyncOperation op = webReq.SendWebRequest();
507-
op.completed += ((ao) => HandleFirebaseDatabaseResponse(op, (res) =>
508-
{
509-
if (OnComplete != null)
510-
OnComplete(new Response<DataSnapshot>(res.message, res.success, res.code, new FirebaseDataSnapshot(this, Json.Deserialize(res.data))));
511-
}));
512529
}
513530

514531
public void Push(object data, int timeout, Action<Response<string>> OnComplete)
@@ -558,10 +575,19 @@ public void RemoveValueAsync(int timeout, Action<Response> OnComplete)
558575
webReq.SetRequestHeader("Content-Type", "application/json");
559576
webReq.timeout = timeout;
560577

561-
if (FirebaseAuth.Instance.IsSignedIn)
562-
webReq.url = webReq.url + "?auth=" + FirebaseAuth.Instance.AccessToken;
563-
UnityWebRequestAsyncOperation op = webReq.SendWebRequest();
564-
op.completed += ((ao) => HandleFirebaseDatabaseResponse(op, OnComplete));
578+
Action sendRequest = () => {
579+
var op = webReq.SendWebRequest();
580+
op.completed += ((ao) => HandleFirebaseDatabaseResponse(op, OnComplete));
581+
};
582+
583+
if (FirebaseAuth.Instance.IsSignedIn) {
584+
FirebaseAuth.Instance.GetAccessToken((accessToken) => {
585+
webReq.url = webReq.url + "?auth=" + accessToken;
586+
sendRequest();
587+
});
588+
} else {
589+
sendRequest();
590+
}
565591
}
566592

567593
void PushFirebaseData(string dbpath, string rawData, int timeout, Action<Response<string>> OnComplete)
@@ -573,20 +599,26 @@ void PushFirebaseData(string dbpath, string rawData, int timeout, Action<Respons
573599
webReq.SetRequestHeader("Content-Type", "application/json");
574600
webReq.timeout = timeout;
575601

576-
if (FirebaseAuth.Instance.IsSignedIn)
577-
webReq.url = webReq.url + "?auth=" + FirebaseAuth.Instance.AccessToken;
578-
UnityWebRequestAsyncOperation op = webReq.SendWebRequest();
579-
op.completed += ((ao) => HandleFirebaseDatabaseResponse(op, (res) =>
580-
{
581-
string pushedId = null;
582-
if (res.success)
583-
{
584-
Dictionary<string, object> data = Json.Deserialize(res.data) as Dictionary<string, object>;
585-
pushedId = data["name"].ToString();
586-
}
587-
if (OnComplete != null)
588-
OnComplete(new Response<string>(res.message, res.success, res.code, pushedId));
589-
}));
602+
Action sendRequest = () => {
603+
var op = webReq.SendWebRequest();
604+
op.completed += (ao) => HandleFirebaseDatabaseResponse(op, (res) => {
605+
string pushedId = null;
606+
if (res.success) {
607+
Dictionary<string, object> data = Json.Deserialize(res.data) as Dictionary<string, object>;
608+
pushedId = data["name"].ToString();
609+
}
610+
OnComplete?.Invoke(new Response<string>(res.message, res.success, res.code, pushedId));
611+
});
612+
};
613+
614+
if (FirebaseAuth.Instance.IsSignedIn) {
615+
FirebaseAuth.Instance.GetAccessToken(accessToken => {
616+
webReq.url = webReq.url + "?auth=" + accessToken;
617+
sendRequest();
618+
});
619+
} else {
620+
sendRequest();
621+
}
590622
}
591623

592624
void WriteFirebaseData(string dbpath, object data, int timeout, string requestMethod, Action<Response> OnComplete)
@@ -598,10 +630,19 @@ void WriteFirebaseData(string dbpath, object data, int timeout, string requestMe
598630
webReq.SetRequestHeader("Content-Type", "application/json");
599631
webReq.timeout = timeout;
600632

601-
if (FirebaseAuth.Instance.IsSignedIn)
602-
webReq.url = webReq.url + "?auth=" + FirebaseAuth.Instance.AccessToken;
603-
UnityWebRequestAsyncOperation op = webReq.SendWebRequest();
604-
op.completed += ((ao) => HandleFirebaseDatabaseResponse(op, OnComplete));
633+
Action sendRequest = () => {
634+
var op = webReq.SendWebRequest();
635+
op.completed += ((ao) => HandleFirebaseDatabaseResponse(op, OnComplete));
636+
};
637+
638+
if (FirebaseAuth.Instance.IsSignedIn) {
639+
FirebaseAuth.Instance.GetAccessToken((accessToken) => {
640+
webReq.url = webReq.url + "?auth=" + accessToken;
641+
sendRequest();
642+
});
643+
} else {
644+
sendRequest();
645+
}
605646
}
606647

607648
void HandleFirebaseDatabaseResponse(UnityWebRequestAsyncOperation webReqOp, Action<Response> OnComplete)

0 commit comments

Comments
 (0)