1
+
2
+ using System ;
3
+ using System . Collections ;
4
+ using System . Collections . Generic ;
5
+ using System . Text ;
6
+ using MiniJSON ;
7
+ using UnityEngine ;
8
+ using UnityEngine . Networking ;
9
+ namespace FirebaseREST
10
+ {
11
+ public class FirebaseAuth : MonoBehaviour
12
+ {
13
+ readonly string EMAIL_AUTH_URL = "https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyPassword?key=" + FirebaseSettings . WEB_API ;
14
+ readonly string CUSTOM_TOKEN_AUTH_URL = "https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyCustomToken?key=" + FirebaseSettings . WEB_API ;
15
+ readonly string REFRESH_TOKEN_URL = "https://securetoken.googleapis.com/v1/token?key=" + FirebaseSettings . WEB_API ;
16
+ readonly string USER_INFO_URL = "https://www.googleapis.com/identitytoolkit/v3/relyingparty/getAccountInfo?key=" + FirebaseSettings . WEB_API ;
17
+ TokenData tokenData ;
18
+
19
+ public TokenData TokenData { get { return tokenData ; } set { this . tokenData = value ; } }
20
+
21
+ private static bool applicationIsQuitting = false ;
22
+ private static FirebaseAuth _instance ;
23
+ private static object _lock = new object ( ) ;
24
+ public static FirebaseAuth Instance
25
+ {
26
+ get
27
+ {
28
+ if ( applicationIsQuitting )
29
+ {
30
+ return null ;
31
+ }
32
+
33
+ lock ( _lock )
34
+ {
35
+ if ( _instance == null )
36
+ {
37
+ _instance = ( FirebaseAuth ) FindObjectOfType ( typeof ( FirebaseAuth ) ) ;
38
+
39
+ if ( FindObjectsOfType ( typeof ( FirebaseAuth ) ) . Length > 1 )
40
+ {
41
+ Debug . LogError ( "there should never be more than 1 singleton!" ) ;
42
+ return _instance ;
43
+ }
44
+
45
+ if ( _instance == null )
46
+ {
47
+ GameObject singleton = new GameObject ( ) ;
48
+ _instance = singleton . AddComponent < FirebaseAuth > ( ) ;
49
+ singleton . name = "(singleton) " + typeof ( FirebaseAuth ) . ToString ( ) ;
50
+ DontDestroyOnLoad ( singleton ) ;
51
+ Debug . Log ( typeof ( FirebaseAuth ) . ToString ( ) + " singleton created" ) ;
52
+ }
53
+ else
54
+ {
55
+ Debug . Log ( "instance already created: " + _instance . gameObject . name ) ;
56
+ }
57
+ }
58
+ return _instance ;
59
+ }
60
+ }
61
+ }
62
+
63
+ void OnDestroy ( )
64
+ {
65
+ applicationIsQuitting = true ;
66
+ }
67
+
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
+ }
84
+ }
85
+
86
+ void Awake ( )
87
+ {
88
+
89
+ }
90
+
91
+ public void FetchUserInfo ( int timeout , Action < Response < List < UserData > > > OnComplete )
92
+ {
93
+ if ( tokenData == null )
94
+ throw new Exception ( "User has not logged in" ) ;
95
+ UnityWebRequestAsyncOperation op = StartRequest ( USER_INFO_URL , "POST" , new Dictionary < string , object > ( ) {
96
+ { "idToken" , tokenData . idToken }
97
+ } , timeout ) ;
98
+ op . completed += ( ( ao ) => HandleFirebaseResponse ( op , ( res ) =>
99
+ {
100
+ Dictionary < string , object > map = Json . Deserialize ( res . data ) as Dictionary < string , object > ;
101
+ List < object > userDatas = Json . Deserialize ( Json . Serialize ( map [ "users" ] ) ) as List < object > ;
102
+ List < UserData > dataToReturn = new List < UserData > ( ) ;
103
+ for ( int i = 0 ; i < userDatas . Count ; i ++ )
104
+ {
105
+ Dictionary < string , object > userMap = Json . Deserialize ( Json . Serialize ( userDatas [ i ] ) ) as Dictionary < string , object > ;
106
+ UserData ud = new UserData ( ) ;
107
+ ud . createdAt = userMap . ContainsKey ( "createdAt" ) ? long . Parse ( userMap [ "createdAt" ] . ToString ( ) ) : 0L ;
108
+ ud . customAuth = userMap . ContainsKey ( "customAuth" ) ? bool . Parse ( userMap [ "customAuth" ] . ToString ( ) ) : false ;
109
+ ud . disabled = userMap . ContainsKey ( "disabled" ) ? bool . Parse ( userMap [ "disabled" ] . ToString ( ) ) : false ;
110
+ ud . displayName = userMap . ContainsKey ( "displayName" ) ? userMap [ "displayName" ] . ToString ( ) : null ;
111
+ ud . email = userMap . ContainsKey ( "email" ) ? userMap [ "email" ] . ToString ( ) : null ;
112
+ ud . emailVerified = userMap . ContainsKey ( "emailVerified" ) ? bool . Parse ( userMap [ "emailVerified" ] . ToString ( ) ) : false ;
113
+ ud . lastLoginAt = userMap . ContainsKey ( "lastLoginAt" ) ? long . Parse ( userMap [ "lastLoginAt" ] . ToString ( ) ) : 0L ;
114
+ ud . localId = userMap . ContainsKey ( "localId" ) ? userMap [ "localId" ] . ToString ( ) : null ;
115
+ ud . passwordUpdatedAt = userMap . ContainsKey ( "passwordUpdatedAt" ) ? long . Parse ( userMap [ "passwordUpdatedAt" ] . ToString ( ) ) : 0L ;
116
+ ud . photoUrl = userMap . ContainsKey ( "photoUrl" ) ? userMap [ "photoUrl" ] . ToString ( ) : null ;
117
+ ud . validSince = userMap . ContainsKey ( "photoUrl" ) ? userMap [ "validSince" ] . ToString ( ) : null ;
118
+ if ( userMap . ContainsKey ( "providerUserInfo" ) )
119
+ {
120
+ ud . providerUserInfo = new List < ProviderInfo > ( ) ;
121
+ List < object > providers = Json . Deserialize ( Json . Serialize ( userMap [ "providerUserInfo" ] ) ) as List < object > ;
122
+ for ( int j = 0 ; j < providers . Count ; j ++ )
123
+ {
124
+ ProviderInfo providerInfo = new ProviderInfo ( ) ;
125
+ Dictionary < string , object > obj = Json . Deserialize ( Json . Serialize ( providers [ j ] ) ) as Dictionary < string , object > ;
126
+ providerInfo . federatedId = obj [ "federatedId" ] . ToString ( ) ;
127
+ providerInfo . providerId = obj [ "providerId" ] . ToString ( ) ;
128
+ ud . providerUserInfo . Add ( providerInfo ) ;
129
+ }
130
+ }
131
+ dataToReturn . Add ( ud ) ;
132
+ }
133
+ if ( OnComplete != null )
134
+ OnComplete ( new Response < List < UserData > > ( "success" , true , res . code , dataToReturn ) ) ;
135
+ } ) ) ;
136
+ }
137
+
138
+ public void RefreshAccessToken ( int timeout , Action < Response < TokenData > > OnComplete )
139
+ {
140
+ if ( tokenData == null )
141
+ throw new Exception ( "User has not logged in" ) ;
142
+ UnityWebRequestAsyncOperation op = StartRequest ( REFRESH_TOKEN_URL , "POST" , new Dictionary < string , object > ( ) {
143
+ { "grant_type" , "refresh_token" } , { "refresh_token" , tokenData . refreshToken }
144
+ } , timeout ) ;
145
+ op . completed += ( ( ao ) => HandleFirebaseResponse ( op , ( res ) =>
146
+ {
147
+ Dictionary < string , object > dataMap = Json . Deserialize ( op . webRequest . downloadHandler . text ) as Dictionary < string , object > ;
148
+ this . tokenData = new TokenData ( ) ;
149
+ tokenData . expiresIn = dataMap [ "expires_in" ] . ToString ( ) ;
150
+ tokenData . idToken = dataMap [ "id_token" ] . ToString ( ) ;
151
+ tokenData . refreshToken = dataMap [ "refresh_token" ] . ToString ( ) ;
152
+ if ( OnComplete != null )
153
+ OnComplete ( new Response < TokenData > ( "success" , true , ( int ) op . webRequest . responseCode , tokenData ) ) ;
154
+ } ) ) ;
155
+ }
156
+
157
+ public void SignInWithCustomToken ( string customToken , int timeout , Action < Response < TokenData > > OnComplete )
158
+ {
159
+ UnityWebRequestAsyncOperation op = StartRequest ( CUSTOM_TOKEN_AUTH_URL , "POST" , new Dictionary < string , object > ( ) {
160
+ { "token" , customToken } , { "returnSecureToken" , true }
161
+ } , timeout ) ;
162
+ op . completed += ( ( ao ) => HandleFirebaseSignInResponse ( op , OnComplete ) ) ;
163
+ }
164
+
165
+ public void SignInWithEmail ( string email , string password , int timeout , Action < Response < TokenData > > OnComplete )
166
+ {
167
+ UnityWebRequestAsyncOperation op = StartRequest ( EMAIL_AUTH_URL , "POST" , new Dictionary < string , object > ( ) {
168
+ { "email" , email } , { "password" , password } , { "returnSecureToken" , true }
169
+ } , timeout ) ;
170
+ op . completed += ( ( ao ) => HandleFirebaseSignInResponse ( op , OnComplete ) ) ;
171
+ }
172
+
173
+ UnityWebRequestAsyncOperation StartRequest ( string url , string requestMethod , Dictionary < string , object > data , int timeout )
174
+ {
175
+ UnityWebRequest webReq = new UnityWebRequest ( url , requestMethod ) ;
176
+ webReq . downloadHandler = new DownloadHandlerBuffer ( ) ;
177
+ byte [ ] bodyRaw = Encoding . UTF8 . GetBytes ( Json . Serialize ( data ) ) ;
178
+ webReq . uploadHandler = new UploadHandlerRaw ( bodyRaw ) ;
179
+ webReq . SetRequestHeader ( "Content-Type" , "application/json" ) ;
180
+ webReq . timeout = timeout ;
181
+ return webReq . SendWebRequest ( ) ;
182
+ }
183
+
184
+ void HandleFirebaseSignInResponse ( UnityWebRequestAsyncOperation webReqOp , Action < Response < TokenData > > OnComplete )
185
+ {
186
+ if ( webReqOp . webRequest . isNetworkError )
187
+ {
188
+ if ( OnComplete != null )
189
+ OnComplete ( new Response < TokenData > ( webReqOp . webRequest . error , false , 0 , null ) ) ;
190
+ }
191
+ else if ( webReqOp . webRequest . isHttpError )
192
+ {
193
+ Dictionary < string , object > res = Json . Deserialize ( webReqOp . webRequest . downloadHandler . text ) as Dictionary < string , object > ;
194
+ Dictionary < string , object > errorObj = Json . Deserialize ( Json . Serialize ( res [ "error" ] ) ) as Dictionary < string , object > ;
195
+ if ( OnComplete != null )
196
+ OnComplete ( new Response < TokenData > ( errorObj [ "message" ] . ToString ( ) , false , int . Parse ( errorObj [ "code" ] . ToString ( ) ) , null ) ) ;
197
+ }
198
+ else
199
+ {
200
+ if ( OnComplete != null )
201
+ {
202
+ Dictionary < string , object > dataMap = Json . Deserialize ( webReqOp . webRequest . downloadHandler . text ) as Dictionary < string , object > ;
203
+ this . tokenData = new TokenData ( ) ;
204
+ tokenData . expiresIn = dataMap [ "expiresIn" ] . ToString ( ) ;
205
+ tokenData . idToken = dataMap [ "idToken" ] . ToString ( ) ;
206
+ tokenData . refreshToken = dataMap [ "refreshToken" ] . ToString ( ) ;
207
+ OnComplete ( new Response < TokenData > ( "success" , true , ( int ) webReqOp . webRequest . responseCode , tokenData ) ) ;
208
+ }
209
+ }
210
+ }
211
+
212
+ void HandleFirebaseResponse ( UnityWebRequestAsyncOperation webReqOp , Action < Response > OnComplete )
213
+ {
214
+ if ( webReqOp . webRequest . isNetworkError )
215
+ {
216
+ if ( OnComplete != null )
217
+ OnComplete ( new Response ( webReqOp . webRequest . error , false , 0 , null ) ) ;
218
+ }
219
+ else if ( webReqOp . webRequest . isHttpError )
220
+ {
221
+ Dictionary < string , object > res = Json . Deserialize ( webReqOp . webRequest . downloadHandler . text ) as Dictionary < string , object > ;
222
+ Dictionary < string , object > errorObj = Json . Deserialize ( Json . Serialize ( res [ "error" ] ) ) as Dictionary < string , object > ;
223
+ if ( OnComplete != null )
224
+ OnComplete ( new Response ( errorObj [ "message" ] . ToString ( ) , false , int . Parse ( errorObj [ "code" ] . ToString ( ) ) , null ) ) ;
225
+ }
226
+ else
227
+ {
228
+ if ( OnComplete != null )
229
+ OnComplete ( new Response ( "success" , true , ( int ) webReqOp . webRequest . responseCode , webReqOp . webRequest . downloadHandler . text ) ) ;
230
+ }
231
+ }
232
+ }
233
+ }
0 commit comments