package com.thebluealliance.androidclient.auth.firebase; 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.thebluealliance.androidclient.TbaLogger; import com.thebluealliance.androidclient.auth.AuthProvider; import com.thebluealliance.androidclient.auth.User; import com.thebluealliance.androidclient.auth.google.GoogleAuthProvider; import com.thebluealliance.androidclient.auth.google.GoogleSignInUser; import android.content.Intent; import javax.annotation.Nullable; import javax.inject.Singleton; import rx.Observable; import rx.Subscriber; @Singleton public class FirebaseAuthProvider implements AuthProvider { private final @Nullable FirebaseAuth mFirebaseAuth; private final GoogleAuthProvider mGoogleAuthProvider; public FirebaseAuthProvider( @Nullable FirebaseAuth firebaseAuth, GoogleAuthProvider googleProvider) { mFirebaseAuth = firebaseAuth; mGoogleAuthProvider = googleProvider; } @Override public void onStart() { mGoogleAuthProvider.onStart(); } @Override public void onStop() { mGoogleAuthProvider.onStop(); } @Override public boolean isUserSignedIn() { return mFirebaseAuth != null && mFirebaseAuth.getCurrentUser() != null; } @Override @Nullable public User getCurrentUser() { if (mFirebaseAuth == null) { return null; } FirebaseUser firebaseUser = mFirebaseAuth.getCurrentUser(); if (firebaseUser == null) { return null; } return new FirebaseSignInUser(firebaseUser); } @Nullable @Override public Intent buildSignInIntent() { return mGoogleAuthProvider.buildSignInIntent(); } @Override public Observable<FirebaseSignInUser> userFromSignInResult(int requestCode, int resultCode, Intent data) { Observable<? extends User> googleUser = mGoogleAuthProvider.userFromSignInResult(requestCode, resultCode, data); return googleUser.switchMap(user -> { if (mFirebaseAuth == null || !(user instanceof GoogleSignInUser)) { return Observable.empty(); } GoogleSignInUser googleSignInUser = (GoogleSignInUser) user; AuthCredential credential = mGoogleAuthProvider .getAuthCredential(googleSignInUser.getIdToken()); return Observable.create(new Observable.OnSubscribe<FirebaseSignInUser>() { @Override public void call(Subscriber<? super FirebaseSignInUser> subscriber) { mFirebaseAuth.signInWithCredential(credential) .addOnCompleteListener(task -> { if (task.isSuccessful()) { AuthResult result = task.getResult(); subscriber.onNext(new FirebaseSignInUser(result.getUser())); } subscriber.onCompleted(); }) .addOnFailureListener(subscriber::onError); } }); }); } /** * Migrate a pre-Firebase user and try and sign it in with Firebase */ public Observable<FirebaseSignInUser> signInLegacyUser() { Observable<? extends User> googleUser = mGoogleAuthProvider.signInLegacyUser(); return googleUser.switchMap(user -> { if (mFirebaseAuth == null || !(user instanceof GoogleSignInUser)) { TbaLogger.w("Unable to attempt firebase login"); return Observable.empty(); } GoogleSignInUser googleSignInUser = (GoogleSignInUser) user; AuthCredential credential = mGoogleAuthProvider .getAuthCredential(googleSignInUser.getIdToken()); return Observable.create(new Observable.OnSubscribe<FirebaseSignInUser>() { @Override public void call(Subscriber<? super FirebaseSignInUser> subscriber) { mFirebaseAuth.signInWithCredential(credential) .addOnCompleteListener(task -> { if (task.isSuccessful()) { AuthResult result = task.getResult(); subscriber.onNext(new FirebaseSignInUser(result.getUser())); } subscriber.onCompleted(); }) .addOnFailureListener(subscriber::onError); } }); }); } }