-
Notifications
You must be signed in to change notification settings - Fork 66
Expand file tree
/
Copy pathRxFirebaseAuth.java
More file actions
352 lines (329 loc) · 16.9 KB
/
RxFirebaseAuth.java
File metadata and controls
352 lines (329 loc) · 16.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
package durdinapps.rxfirebase2;
import static durdinapps.rxfirebase2.Plugins.throwExceptionIfMainThread;
import androidx.annotation.NonNull;
import com.google.firebase.auth.ActionCodeResult;
import com.google.firebase.auth.AuthCredential;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.auth.SignInMethodQueryResult;
import io.reactivex.Completable;
import io.reactivex.CompletableEmitter;
import io.reactivex.CompletableOnSubscribe;
import io.reactivex.Maybe;
import io.reactivex.MaybeEmitter;
import io.reactivex.MaybeOnSubscribe;
import io.reactivex.Observable;
public class RxFirebaseAuth {
/**
* Asynchronously signs in as an anonymous user.
* If there is already an anonymous user signed in, that user will be returned; otherwise, a new anonymous user identity will be created and returned.
*
* @param firebaseAuth firebaseAuth instance.
* @return a {@link Maybe} which emits an {@link AuthResult} if success.
* @see <a href="https://firebase.google.com/docs/reference/android/com/google/firebase/auth/FirebaseAuth">Firebase Auth API</a>
*/
@NonNull
public static Maybe<AuthResult> signInAnonymously(@NonNull final FirebaseAuth firebaseAuth) {
return Maybe.create(new MaybeOnSubscribe<AuthResult>() {
@Override
public void subscribe(MaybeEmitter<AuthResult> emitter) throws Exception {
RxHandler.assignOnTask(emitter, firebaseAuth.signInAnonymously());
}
});
}
/**
* Asynchronously signs in using an email and password.
* Fails with an error if the email address and password do not match.
* <p>
* Note: The user's password is NOT the password used to access the user's email account.
* The email address serves as a unique identifier for the user, and the password is used to access the user's account in your Firebase project.
*
* @param firebaseAuth firebaseAuth instance.
* @param email email to login.
* @param password password to login.
* @return a {@link Maybe} which emits an {@link AuthResult} if success.
* @see <a href="https://firebase.google.com/docs/reference/android/com/google/firebase/auth/FirebaseAuth">Firebase Auth API</a>
*/
@NonNull
public static Maybe<AuthResult> signInWithEmailAndPassword(@NonNull final FirebaseAuth firebaseAuth,
@NonNull final String email,
@NonNull final String password) {
return Maybe.create(new MaybeOnSubscribe<AuthResult>() {
@Override
public void subscribe(MaybeEmitter<AuthResult> emitter) throws Exception {
RxHandler.assignOnTask(emitter, firebaseAuth.signInWithEmailAndPassword(email, password));
}
});
}
/**
* Asynchronously signs in with the given credentials.
*
* @param firebaseAuth firebaseAuth instance.
* @param credential The auth credential. Value must not be null.
* @return a {@link Maybe} which emits an {@link AuthResult} if success.
* @see <a href="https://firebase.google.com/docs/reference/android/com/google/firebase/auth/FirebaseAuth">Firebase Auth API</a>
*/
@NonNull
public static Maybe<AuthResult> signInWithCredential(@NonNull final FirebaseAuth firebaseAuth,
@NonNull final AuthCredential credential) {
return Maybe.create(new MaybeOnSubscribe<AuthResult>() {
@Override
public void subscribe(MaybeEmitter<AuthResult> emitter) throws Exception {
RxHandler.assignOnTask(emitter, firebaseAuth.signInWithCredential(credential));
}
});
}
/**
* Asynchronously signs in using a custom token.
* <p>
* Custom tokens are used to integrate Firebase Auth with existing auth systems, and must be generated by the auth backend.
* <p>
* Fails with an error if the token is invalid, expired, or not accepted by the Firebase Auth service.
*
* @param firebaseAuth firebaseAuth instance.
* @param token The custom token to sign in with.
* @return a {@link Maybe} which emits an {@link AuthResult} if success.
* @see <a href="https://firebase.google.com/docs/reference/android/com/google/firebase/auth/FirebaseAuth">Firebase Auth API</a>
*/
@NonNull
public static Maybe<AuthResult> signInWithCustomToken(@NonNull final FirebaseAuth firebaseAuth,
@NonNull final String token) {
return Maybe.create(new MaybeOnSubscribe<AuthResult>() {
@Override
public void subscribe(MaybeEmitter<AuthResult> emitter) throws Exception {
RxHandler.assignOnTask(emitter, firebaseAuth.signInWithCustomToken(token));
}
});
}
/**
* Creates a new user account associated with the specified email address and password.
* <p>
* On successful creation of the user account, this user will also be signed in to your application.
* <p>
* User account creation can fail if the account already exists or the password is invalid.
* <p>
* Note: The email address acts as a unique identifier for the user and enables an email-based password reset.
* This function will create a new user account and set the initial user password.
* <p>
* Custom tokens are used to integrate Firebase Auth with existing auth systems, and must be generated by the auth backend.
* <p>
* Fails with an error if the token is invalid, expired, or not accepted by the Firebase Auth service.
*
* @param firebaseAuth firebaseAuth instance.
* @param email The user's email address.
* @param password The user's chosen password.
* @return a {@link Maybe} which emits an {@link AuthResult} if success.
* @see <a href="https://firebase.google.com/docs/reference/android/com/google/firebase/auth/FirebaseAuth">Firebase Auth API</a>
*/
@NonNull
public static Maybe<AuthResult> createUserWithEmailAndPassword(@NonNull final FirebaseAuth firebaseAuth,
@NonNull final String email,
@NonNull final String password) {
return Maybe.create(new MaybeOnSubscribe<AuthResult>() {
@Override
public void subscribe(MaybeEmitter<AuthResult> emitter) throws Exception {
RxHandler.assignOnTask(emitter, firebaseAuth.createUserWithEmailAndPassword(email, password));
}
});
}
/**
* Gets the list of provider IDs that can be used to sign in for the given email address. Useful for an "identifier-first" sign-in flow.
*
* @param firebaseAuth firebaseAuth instance.
* @param email An email address.
* @return a {@link Maybe} which emits an {@link SignInMethodQueryResult} if success.
* @see <a href="https://firebase.google.com/docs/reference/android/com/google/firebase/auth/FirebaseAuth">Firebase Auth API</a>
*/
@NonNull
public static Maybe<SignInMethodQueryResult> fetchSignInMethodsForEmail(@NonNull final FirebaseAuth firebaseAuth,
@NonNull final String email) {
return Maybe.create(new MaybeOnSubscribe<SignInMethodQueryResult>() {
@Override
public void subscribe(MaybeEmitter<SignInMethodQueryResult> emitter) {
RxHandler.assignOnTask(emitter, firebaseAuth.fetchSignInMethodsForEmail(email));
}
});
}
/**
* Sends a password reset email to the given email address.
* <p>
* To complete the password reset, call {@link FirebaseAuth#confirmPasswordReset(String, String)} with the code supplied in
* the email sent to the user, along with the new password specified by the user.
*
* @param firebaseAuth firebaseAuth instance.
* @param email The email address with the password to be reset.
* @return a {@link Completable} which emits when the action is completed.
* @see <a href="https://firebase.google.com/docs/reference/android/com/google/firebase/auth/FirebaseAuth">Firebase Auth API</a>
*/
@NonNull
public static Completable sendPasswordResetEmail(@NonNull final FirebaseAuth firebaseAuth,
@NonNull final String email) {
return Completable.create(new CompletableOnSubscribe() {
@Override
public void subscribe(CompletableEmitter emitter) throws Exception {
RxCompletableHandler.assignOnTask(emitter, firebaseAuth.sendPasswordResetEmail(email));
}
});
}
/**
* Asynchronously sets the provided user as currentUser on the current Auth instance. A new instance copy of the user provided will be made and set as currentUser.
* <p>
* This will trigger firebase.auth.Auth#onAuthStateChanged and firebase.auth.Auth#onIdTokenChanged listeners like other sign in methods.
* @param firebaseAuth firebaseAuth instance.
* @param newUser The new user to update the current instance.
* @return a {@link Completable} which emits when the action is completed.
* @see <a href="https://firebase.google.com/docs/reference/android/com/google/firebase/auth/FirebaseAuth">Firebase Auth API</a>
*/
@NonNull
public static Completable updateCurrentUser(@NonNull final FirebaseAuth firebaseAuth,
@NonNull final FirebaseUser newUser) {
return Completable.create(new CompletableOnSubscribe() {
@Override
public void subscribe(CompletableEmitter emitter) throws Exception {
RxCompletableHandler.assignOnTask(emitter, firebaseAuth.updateCurrentUser(newUser));
}
});
}
/**
* Observable which track the auth changes of {@link FirebaseAuth} to listen when an user is logged or not.
*
* @param firebaseAuth firebaseAuth instance.
* @return an {@link Observable} which emits every time that the {@link FirebaseAuth} state change.
* @throws IllegalStateException if operation is happening on the main thread
* @see Plugins
*/
@NonNull
public static Observable<FirebaseAuth> observeAuthState(@NonNull final FirebaseAuth firebaseAuth) {
return Observable.create(emitter -> {
throwExceptionIfMainThread();
final FirebaseAuth.AuthStateListener authStateListener = emitter::onNext;
firebaseAuth.addAuthStateListener(authStateListener);
emitter.setCancellable(() -> firebaseAuth.removeAuthStateListener(authStateListener));
});
}
/**
* Checks that the code given is valid. This code will have been generated
* by {@link FirebaseAuth#sendPasswordResetEmail(String)} or {@link com.google.firebase.auth.FirebaseUser#sendEmailVerification()} valid for a single use.
*
* @param firebaseAuth firebaseAuth instance.
* @param code generated code by firebase.
* @return a {@link Maybe} which emits when the action is completed.
*/
@NonNull
public static Maybe<ActionCodeResult> checkActionCode(@NonNull final FirebaseAuth firebaseAuth,
@NonNull final String code) {
return Maybe.create(new MaybeOnSubscribe<ActionCodeResult>() {
@Override
public void subscribe(MaybeEmitter<ActionCodeResult> emitter) throws Exception {
RxHandler.assignOnTask(emitter, firebaseAuth.checkActionCode(code));
}
});
}
/**
* Changes the user's password to newPassword for the account for which the code is valid.
* Code validity can be checked with {@link FirebaseAuth#verifyPasswordResetCode(String)}.
* This use case is only valid for signed-out users, and behavior is undefined for signed-in users.
* Password changes for signed-in users should be made using {@link com.google.firebase.auth.FirebaseUser#updatePassword(String)}.
*
* @param firebaseAuth firebaseAuth instance.
* @param code generated code by firebase.
* @param newPassword new password for the user.
* @return a {@link Completable} which emits when the action is completed.
*/
@NonNull
public static Completable confirmPasswordReset(@NonNull final FirebaseAuth firebaseAuth,
@NonNull final String code,
@NonNull final String newPassword) {
return Completable.create(new CompletableOnSubscribe() {
@Override
public void subscribe(CompletableEmitter emitter) throws Exception {
RxCompletableHandler.assignOnTask(emitter, firebaseAuth.confirmPasswordReset(code, newPassword));
}
});
}
/**
* Applies the given code, which can be any out of band code which is valid according
* to {@link FirebaseAuth#checkActionCode(String)} that does not also pass {@link FirebaseAuth#{verifyPasswordResetCode(String)},
* which requires an additional parameter.
*
* @param firebaseAuth firebaseAuth instance.
* @param code generated code by firebase.
* @return a {@link Completable} which emits when the action is completed.
*/
@NonNull
public static Completable applyActionCode(@NonNull final FirebaseAuth firebaseAuth,
@NonNull final String code) {
return Completable.create(new CompletableOnSubscribe() {
@Override
public void subscribe(CompletableEmitter emitter) throws Exception {
RxCompletableHandler.assignOnTask(emitter, firebaseAuth.applyActionCode(code));
}
});
}
/**
* Checks that the code is a valid password reset out of band code.
* This code will have been generated by a call to {@link FirebaseAuth#sendPasswordResetEmail(String)}, and is valid for a single use.
*
* @param firebaseAuth firebaseAuth instance.
* @param code generated code by firebase.
* @return a {@link Maybe} which emits when the action is completed.
*/
@NonNull
public static Maybe<String> verifyPasswordResetCode(@NonNull final FirebaseAuth firebaseAuth,
@NonNull final String code) {
return Maybe.create(new MaybeOnSubscribe<String>() {
@Override
public void subscribe(MaybeEmitter<String> emitter) throws Exception {
RxHandler.assignOnTask(emitter, firebaseAuth.verifyPasswordResetCode(code));
}
});
}
/**
* Registers a listener to changes in the ID token state.
* There can be more than one listener registered at the same time. The listeners are called asynchronously, possibly on a different thread.
* <p>
* Authentication state changes are:
* <p>
* -When a user signs in
* -When the current user signs out
* -When the current user changes
* -When there is a change in the current user's token
* <p>
* Use RemoveIdTokenListener to unregister a listener.
*
* @param firebaseAuth firebaseAuth instance.
* @param idTokenListener given token listener.
* @return a {@link Completable} which emits when the action is completed.
*/
@NonNull
public static Completable addIdTokenListener(@NonNull final FirebaseAuth firebaseAuth,
@NonNull final FirebaseAuth.IdTokenListener idTokenListener) {
return Completable.create(new CompletableOnSubscribe() {
@Override
public void subscribe(CompletableEmitter emitter) throws Exception {
firebaseAuth.addIdTokenListener(idTokenListener);
emitter.onComplete();
}
});
}
/**
* Unregisters a listener of ID token changes.
* Listener must previously been added with AddIdTokenListener.
*
* @param firebaseAuth firebaseAuth instance.
* @param idTokenListener given token listener.
* @return a {@link Completable} which emits when the action is completed.
*/
@NonNull
public static Completable removeIdTokenListener(@NonNull final FirebaseAuth firebaseAuth,
@NonNull final FirebaseAuth.IdTokenListener idTokenListener) {
return Completable.create(new CompletableOnSubscribe() {
@Override
public void subscribe(CompletableEmitter emitter) throws Exception {
firebaseAuth.removeIdTokenListener(idTokenListener);
emitter.onComplete();
}
});
}
}