├── firebase-auth ├── .gitignore ├── src │ ├── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ │ └── com │ │ │ └── github │ │ │ └── b3er │ │ │ └── rxfirebase │ │ │ └── auth │ │ │ ├── SignInAnonymouslyOnSubscribe.java │ │ │ ├── SignOutOnSubscribe.java │ │ │ ├── SignInWithCustomTokenOnSubscribe.java │ │ │ ├── UserDeleteOnSubscribe.java │ │ │ ├── UserReloadOnSubscribe.java │ │ │ ├── UserSendEmailVerificationOnSubscribe.java │ │ │ ├── SignInWithCredentialOnSubscribe.java │ │ │ ├── UserUpdateEmailOnSubscribe.java │ │ │ ├── SignInWithEmailAndPasswordOnSubscribe.java │ │ │ ├── CreateUserWithEmailAndPasswordOnSubscribe.java │ │ │ ├── UserUpdatePasswordOnSubscribe.java │ │ │ ├── UserUnlinkOnSubscribe.java │ │ │ ├── ApplyActionCodeOnSubscribe.java │ │ │ ├── SendPasswordResetEmailOnSubscribe.java │ │ │ ├── GetCurrentUserOnSubscribe.java │ │ │ ├── VerifyPasswordResetCodeOnSubscribe.java │ │ │ ├── UserReauthenticateOnSubscribe.java │ │ │ ├── UserUpdateProfileOnSubscribe.java │ │ │ ├── CheckActionCodeOnSubscribe.java │ │ │ ├── UserLinkWithCredentialOnSubscribe.java │ │ │ ├── ConfirmPasswordResetOnSubscribe.java │ │ │ ├── AuthStateChangesOnSubscribe.java │ │ │ ├── UserGetTokenOnSubscribe.java │ │ │ ├── BaseAuthOnSubscribe.java │ │ │ ├── FetchProvidersForEmailOnSubscribe.java │ │ │ ├── RxFirebaseUser.java │ │ │ └── RxFirebaseAuth.java │ └── test │ │ └── java │ │ └── com │ │ └── github │ │ └── b3er │ │ └── rxfirebase │ │ └── auth │ │ └── RxFirebaseUserTest.java ├── gradle.properties ├── proguard-rules.pro └── build.gradle ├── common ├── src │ └── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── com │ │ └── github │ │ └── b3er │ │ └── rxfirebase │ │ └── common │ │ └── GmsTaskListeners.java ├── gradle.properties └── build.gradle ├── firebase-database ├── src │ ├── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ │ └── com │ │ │ └── github │ │ │ └── b3er │ │ │ └── rxfirebase │ │ │ └── database │ │ │ ├── ChildRemoveEvent.java │ │ │ ├── RemoveValueOnSubscribe.java │ │ │ ├── SetValueOnSubscribe.java │ │ │ ├── SetPriorityOnSubscribe.java │ │ │ ├── UpdateChildrenOnSubscribe.java │ │ │ ├── ChildEvent.java │ │ │ ├── SetValueWithPriorityOnSubscribe.java │ │ │ ├── transformers │ │ │ ├── SingleTransformerOfClazz.java │ │ │ ├── ObsTransformerOfClazz.java │ │ │ ├── SingleTransformerOfGenericTypeIndicator.java │ │ │ └── ObsTransformerOfGenericTypeIndicator.java │ │ │ ├── DataOnSubscribe.java │ │ │ ├── DataChangesOnSubscribe.java │ │ │ ├── ChildMoveEvent.java │ │ │ ├── ChildChangeEvent.java │ │ │ ├── ChildAddEvent.java │ │ │ ├── RunTransactionOnSubscribe.java │ │ │ ├── ChildEventsOnSubscribe.java │ │ │ └── RxFirebaseDatabase.java │ └── test │ │ └── java │ │ └── com │ │ └── github │ │ └── b3er │ │ └── rxfirebase │ │ └── database │ │ ├── ChildEventTest.java │ │ └── RxFirebaseDatabaseTest.java ├── gradle.properties └── build.gradle ├── firebase-storage ├── src │ └── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── com │ │ └── github │ │ └── b3er │ │ └── rxfirebase │ │ └── storage │ │ ├── DeleteOnSubscribe.java │ │ ├── GetDownloadUriOnSubscribe.java │ │ ├── GetMetadataOnSubscribe.java │ │ ├── GetStreamOnSubscribe.java │ │ ├── PutBytesOnSubscribe.java │ │ ├── PutFileOnSubscribe.java │ │ ├── GetBytesOnSubscribe.java │ │ ├── UpdateMetadataOnSubscribe.java │ │ ├── GetFileToFileOnSubscribe.java │ │ ├── GetFileToUriOnSubscribe.java │ │ ├── PutStreamOnSubscribe.java │ │ ├── GetStreamWithProcessorOnSubscribe.java │ │ ├── PutBytesWithMetadataOnSubscribe.java │ │ ├── PutFileWithMetadataOnSubscribe.java │ │ ├── PutStreamWithMetadataOnSubscribe.java │ │ ├── PutFileWithMetadataAndExistingUriOnSubscribe.java │ │ └── RxFirebaseStorage.java ├── gradle.properties └── build.gradle ├── firebase-auth-kotlin ├── src │ └── main │ │ ├── AndroidManifest.xml │ │ └── kotlin │ │ └── com │ │ └── github │ │ └── b3er │ │ └── rxfirebase │ │ └── auth │ │ ├── RxFirebaseUser.kt │ │ └── RxFirebaseAuth.kt ├── gradle.properties └── build.gradle ├── gradle ├── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties └── gradle-mvn-push.gradle ├── firebase-database-kotlin ├── src │ └── main │ │ ├── AndroidManifest.xml │ │ └── kotlin │ │ └── com │ │ └── github │ │ └── b3er │ │ └── rxfirebase │ │ └── database │ │ └── RxFirebaseDatabase.kt ├── gradle.properties └── build.gradle ├── firebase-storage-kotlin ├── src │ └── main │ │ ├── AndroidManifest.xml │ │ └── kotlin │ │ └── com │ │ └── github │ │ └── b3er │ │ └── rxfirebase │ │ └── storage │ │ └── RxFirebaseStorage.kt ├── gradle.properties └── build.gradle ├── CONTRIBUTING.md ├── settings.gradle ├── config └── checkstyle │ ├── checkstyle_suppressions.xml │ ├── checkstyle.xsl │ └── checkstyle.xml ├── .gitignore ├── gradle.properties ├── RELEASING.md ├── CHANGELOG.md ├── dependencies.gradle ├── gradlew.bat ├── gradlew ├── LICENSE.txt └── README.md /firebase-auth/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /common/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /common/gradle.properties: -------------------------------------------------------------------------------- 1 | POM_ARTIFACT_ID=common 2 | POM_NAME=RxFirebase2-Common 3 | POM_PACKAGING=aar -------------------------------------------------------------------------------- /firebase-auth/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /firebase-database/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /firebase-storage/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /firebase-auth/gradle.properties: -------------------------------------------------------------------------------- 1 | POM_ARTIFACT_ID=firebase-auth 2 | POM_NAME=RxFirebase2-Auth 3 | POM_PACKAGING=aar -------------------------------------------------------------------------------- /firebase-auth-kotlin/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/b3er/RxFirebase2/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /firebase-database-kotlin/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /firebase-storage-kotlin/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /firebase-storage/gradle.properties: -------------------------------------------------------------------------------- 1 | POM_ARTIFACT_ID=firebase-storage 2 | POM_NAME=RxFirebase2-Storage 3 | POM_PACKAGING=aar -------------------------------------------------------------------------------- /firebase-database/gradle.properties: -------------------------------------------------------------------------------- 1 | POM_ARTIFACT_ID=firebase-database 2 | POM_NAME=RxFirebase2-Database 3 | POM_PACKAGING=aar -------------------------------------------------------------------------------- /firebase-auth-kotlin/gradle.properties: -------------------------------------------------------------------------------- 1 | POM_ARTIFACT_ID=firebase-auth-kotlin 2 | POM_NAME=RxFirebase2-Auth Kotlin support 3 | POM_PACKAGING=aar -------------------------------------------------------------------------------- /firebase-database-kotlin/gradle.properties: -------------------------------------------------------------------------------- 1 | POM_ARTIFACT_ID=firebase-database-kotlin 2 | POM_NAME=RxFirebase2-Database Kotlin support 3 | POM_PACKAGING=aar -------------------------------------------------------------------------------- /firebase-storage-kotlin/gradle.properties: -------------------------------------------------------------------------------- 1 | POM_ARTIFACT_ID=firebase-storage-kotlin 2 | POM_NAME=RxFirebase2-Storage Kotlin support 3 | POM_PACKAGING=aar -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to RxFirebase2 2 | 3 | When contributing, please follow SquareAndroid code style from [square/java-code-styles](https://github.com/square/java-code-styles). -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':common' 2 | include ':firebase-auth', ':firebase-auth-kotlin' 3 | include ':firebase-database', 'firebase-database-kotlin' 4 | include ':firebase-storage', 'firebase-storage-kotlin' 5 | -------------------------------------------------------------------------------- /config/checkstyle/checkstyle_suppressions.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed Feb 01 20:24:23 MSK 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea/ 3 | *.iml 4 | 5 | # Built application files 6 | *.apk 7 | *.ap_ 8 | 9 | # Files for the Dalvik VM 10 | *.dex 11 | 12 | # Java class files 13 | *.class 14 | 15 | # Generated files 16 | bin/ 17 | gen/ 18 | 19 | # Gradle files 20 | .gradle/ 21 | build/ 22 | 23 | # Local configuration file (sdk path, etc) 24 | local.properties 25 | 26 | # Proguard folder generated by Eclipse 27 | proguard/ 28 | 29 | # Captures 30 | captures/ 31 | .project 32 | .classpath 33 | .settings/ -------------------------------------------------------------------------------- /firebase-auth/src/main/java/com/github/b3er/rxfirebase/auth/SignInAnonymouslyOnSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.auth; 2 | 3 | import com.google.android.gms.tasks.Task; 4 | import com.google.firebase.auth.AuthResult; 5 | import com.google.firebase.auth.FirebaseAuth; 6 | 7 | final class SignInAnonymouslyOnSubscribe extends BaseAuthOnSubscribe { 8 | 9 | SignInAnonymouslyOnSubscribe(FirebaseAuth instance) { 10 | super(instance); 11 | } 12 | 13 | @Override protected Task createAuthTask(FirebaseAuth instance) { 14 | return instance.signInAnonymously(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | VERSION_NAME=11.2.1-SNAPSHOT 2 | GROUP=com.github.b3er.rxfirebase 3 | POM_DESCRIPTION=RxJava 2 binding APIs for Firebase Android SDK. 4 | POM_URL=https://github.com/b3er/RxFirebase2 5 | POM_SCM_URL=https://github.com/b3er/RxFirebase2.git 6 | POM_SCM_CONNECTION=scm:git@github.com:b3er/RxFirebase2.git 7 | POM_SCM_DEV_CONNECTION=scm:git@github.com:b3er/RxFirebase2.git 8 | POM_LICENCE_NAME=The Apache Software License, Version 2.0 9 | POM_LICENCE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt 10 | POM_LICENCE_DIST=repo 11 | POM_DEVELOPER_ID=b3er 12 | POM_DEVELOPER_NAME=Ilya Usanov 13 | POM_DEVELOPER_EMAIL=b3er@who.ms 14 | -------------------------------------------------------------------------------- /RELEASING.md: -------------------------------------------------------------------------------- 1 | # Releasing 2 | 3 | 1. Change the version in `gradle.properties` to a non-SNAPSHOT version. 4 | 2. Update the `CHANGELOG.md` for the impending release. 5 | 3. Update the `README.md` with the new version. 6 | 4. `git commit -am "Prepare for release X.Y.Z."` (where X.Y.Z is the new version) 7 | 5. `git tag -a X.Y.Z -m "Version X.Y.Z"` (where X.Y.Z is the new version) 8 | 6. `./gradlew clean uploadArchives` 9 | 7. Update the `gradle.properties` to the next SNAPSHOT version. 10 | 8. `git commit -am "Prepare next development version."` 11 | 9. `git push && git push --tags` 12 | 10. Visit [Sonatype Nexus](https://oss.sonatype.org/) and promote the artifact. 13 | -------------------------------------------------------------------------------- /firebase-auth/src/main/java/com/github/b3er/rxfirebase/auth/SignOutOnSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.auth; 2 | 3 | import com.google.firebase.auth.FirebaseAuth; 4 | import io.reactivex.CompletableEmitter; 5 | import io.reactivex.CompletableOnSubscribe; 6 | 7 | final class SignOutOnSubscribe implements CompletableOnSubscribe { 8 | 9 | private final FirebaseAuth instance; 10 | 11 | SignOutOnSubscribe(FirebaseAuth instance) { 12 | this.instance = instance; 13 | } 14 | 15 | @Override public void subscribe(CompletableEmitter emitter) { 16 | if (!emitter.isDisposed()) { 17 | instance.signOut(); 18 | emitter.onComplete(); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | ## Version 11.2.0 *(2017/07/06)* 3 | * Updated firebase version to 11.0.2 4 | * Updated kotlin to 1.1.2 5 | ## Version 10.21.2 *(2017/03/29)* 6 | * Updated kotlin and android plugins version 7 | * Added rx prefix to kotlin extension functions in storage 8 | * Changed `Single>` to `Maybe<...>` in auth 9 | 10 | ## Version 10.21.1 *(2017/03/22)* 11 | Added rxRemove() in firebase-database-kotlin 12 | 13 | ## Version 10.21.0 *(2017/03/22)* 14 | Updated firebase version to 10.2.1 15 | 16 | Updated kotlin version to 1.1.1 17 | 18 | ## Version 10.1.1 *(2017/02/03)* 19 | 20 | Changed artifacts group and names 21 | 22 | ## Version 10.1.0 *(2017/02/01)* 23 | 24 | Initial release. -------------------------------------------------------------------------------- /firebase-auth/src/main/java/com/github/b3er/rxfirebase/auth/SignInWithCustomTokenOnSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.auth; 2 | 3 | import com.google.android.gms.tasks.Task; 4 | import com.google.firebase.auth.AuthResult; 5 | import com.google.firebase.auth.FirebaseAuth; 6 | 7 | final class SignInWithCustomTokenOnSubscribe extends BaseAuthOnSubscribe { 8 | 9 | private final String token; 10 | 11 | SignInWithCustomTokenOnSubscribe(FirebaseAuth instance, String token) { 12 | super(instance); 13 | this.token = token; 14 | } 15 | 16 | @Override protected Task createAuthTask(FirebaseAuth instance) { 17 | return instance.signInWithCustomToken(token); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /firebase-auth/src/main/java/com/github/b3er/rxfirebase/auth/UserDeleteOnSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.auth; 2 | 3 | import com.github.b3er.rxfirebase.common.GmsTaskListeners; 4 | import com.google.firebase.auth.FirebaseUser; 5 | import io.reactivex.CompletableEmitter; 6 | import io.reactivex.CompletableOnSubscribe; 7 | 8 | final class UserDeleteOnSubscribe implements CompletableOnSubscribe { 9 | 10 | private final FirebaseUser user; 11 | 12 | UserDeleteOnSubscribe(FirebaseUser user) { 13 | this.user = user; 14 | } 15 | 16 | @Override public void subscribe(CompletableEmitter emitter) { 17 | user.delete().addOnCompleteListener(GmsTaskListeners.listener(emitter)); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /firebase-auth/src/main/java/com/github/b3er/rxfirebase/auth/UserReloadOnSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.auth; 2 | 3 | import com.github.b3er.rxfirebase.common.GmsTaskListeners; 4 | import com.google.firebase.auth.FirebaseUser; 5 | import io.reactivex.CompletableEmitter; 6 | import io.reactivex.CompletableOnSubscribe; 7 | 8 | final class UserReloadOnSubscribe implements CompletableOnSubscribe { 9 | 10 | private final FirebaseUser user; 11 | 12 | UserReloadOnSubscribe(FirebaseUser user) { 13 | this.user = user; 14 | } 15 | 16 | @Override public void subscribe(CompletableEmitter emitter) { 17 | user.reload().addOnCompleteListener(GmsTaskListeners.listener(emitter)); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /firebase-auth/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/kunny/android-sdk-osx/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /firebase-database/src/main/java/com/github/b3er/rxfirebase/database/ChildRemoveEvent.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.database; 2 | 3 | import android.support.annotation.CheckResult; 4 | import android.support.annotation.NonNull; 5 | import com.google.firebase.database.DataSnapshot; 6 | 7 | public final class ChildRemoveEvent extends ChildEvent { 8 | 9 | private ChildRemoveEvent(DataSnapshot dataSnapshot) { 10 | super(dataSnapshot); 11 | } 12 | 13 | @CheckResult @NonNull public static ChildRemoveEvent create(DataSnapshot dataSnapshot) { 14 | return new ChildRemoveEvent(dataSnapshot); 15 | } 16 | 17 | @Override public String toString() { 18 | return "ChildRemoveEvent{" + "dataSnapshot=" + dataSnapshot + '}'; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /firebase-database/src/main/java/com/github/b3er/rxfirebase/database/RemoveValueOnSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.database; 2 | 3 | import com.github.b3er.rxfirebase.common.GmsTaskListeners; 4 | import com.google.firebase.database.DatabaseReference; 5 | import io.reactivex.CompletableEmitter; 6 | import io.reactivex.CompletableOnSubscribe; 7 | 8 | final class RemoveValueOnSubscribe implements CompletableOnSubscribe { 9 | 10 | private final DatabaseReference ref; 11 | 12 | RemoveValueOnSubscribe(DatabaseReference ref) { 13 | this.ref = ref; 14 | } 15 | 16 | @Override public void subscribe(final CompletableEmitter emitter) { 17 | ref.removeValue().addOnCompleteListener(GmsTaskListeners.listener(emitter)); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /firebase-storage/src/main/java/com/github/b3er/rxfirebase/storage/DeleteOnSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.storage; 2 | 3 | import com.github.b3er.rxfirebase.common.GmsTaskListeners; 4 | import com.google.firebase.storage.StorageReference; 5 | import io.reactivex.CompletableEmitter; 6 | import io.reactivex.CompletableOnSubscribe; 7 | 8 | final class DeleteOnSubscribe implements CompletableOnSubscribe { 9 | 10 | private final StorageReference mRef; 11 | 12 | DeleteOnSubscribe(StorageReference reference) { 13 | this.mRef = reference; 14 | } 15 | 16 | @Override public void subscribe(CompletableEmitter emitter) throws Exception { 17 | mRef.delete().addOnCompleteListener(GmsTaskListeners.listener(emitter)); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /firebase-auth/src/main/java/com/github/b3er/rxfirebase/auth/UserSendEmailVerificationOnSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.auth; 2 | 3 | import com.github.b3er.rxfirebase.common.GmsTaskListeners; 4 | import com.google.firebase.auth.FirebaseUser; 5 | import io.reactivex.CompletableEmitter; 6 | import io.reactivex.CompletableOnSubscribe; 7 | 8 | final class UserSendEmailVerificationOnSubscribe implements CompletableOnSubscribe { 9 | 10 | private final FirebaseUser user; 11 | 12 | UserSendEmailVerificationOnSubscribe(FirebaseUser user) { 13 | this.user = user; 14 | } 15 | 16 | @Override public void subscribe(CompletableEmitter emitter) { 17 | user.sendEmailVerification().addOnCompleteListener(GmsTaskListeners.listener(emitter)); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /firebase-storage/src/main/java/com/github/b3er/rxfirebase/storage/GetDownloadUriOnSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.storage; 2 | 3 | import android.net.Uri; 4 | import com.github.b3er.rxfirebase.common.GmsTaskListeners; 5 | import com.google.firebase.storage.StorageReference; 6 | import io.reactivex.SingleEmitter; 7 | import io.reactivex.SingleOnSubscribe; 8 | 9 | final class GetDownloadUriOnSubscribe implements SingleOnSubscribe { 10 | 11 | private final StorageReference mRef; 12 | 13 | GetDownloadUriOnSubscribe(StorageReference ref) { 14 | this.mRef = ref; 15 | } 16 | 17 | @Override public void subscribe(SingleEmitter e) throws Exception { 18 | mRef.getDownloadUrl().addOnCompleteListener(GmsTaskListeners.listener(e)); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /firebase-auth/src/main/java/com/github/b3er/rxfirebase/auth/SignInWithCredentialOnSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.auth; 2 | 3 | import com.google.android.gms.tasks.Task; 4 | import com.google.firebase.auth.AuthCredential; 5 | import com.google.firebase.auth.AuthResult; 6 | import com.google.firebase.auth.FirebaseAuth; 7 | 8 | final class SignInWithCredentialOnSubscribe extends BaseAuthOnSubscribe { 9 | 10 | private final AuthCredential credential; 11 | 12 | SignInWithCredentialOnSubscribe(FirebaseAuth instance, AuthCredential credential) { 13 | super(instance); 14 | this.credential = credential; 15 | } 16 | 17 | @Override protected Task createAuthTask(FirebaseAuth instance) { 18 | return instance.signInWithCredential(credential); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /firebase-database/src/main/java/com/github/b3er/rxfirebase/database/SetValueOnSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.database; 2 | 3 | import com.github.b3er.rxfirebase.common.GmsTaskListeners; 4 | import com.google.firebase.database.DatabaseReference; 5 | import io.reactivex.CompletableEmitter; 6 | import io.reactivex.CompletableOnSubscribe; 7 | 8 | final class SetValueOnSubscribe implements CompletableOnSubscribe { 9 | 10 | private final DatabaseReference ref; 11 | 12 | private final T value; 13 | 14 | SetValueOnSubscribe(DatabaseReference ref, T value) { 15 | this.ref = ref; 16 | this.value = value; 17 | } 18 | 19 | @Override public void subscribe(CompletableEmitter emitter) { 20 | ref.setValue(value).addOnCompleteListener(GmsTaskListeners.listener(emitter)); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /firebase-storage/src/main/java/com/github/b3er/rxfirebase/storage/GetMetadataOnSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.storage; 2 | 3 | import com.github.b3er.rxfirebase.common.GmsTaskListeners; 4 | import com.google.firebase.storage.StorageMetadata; 5 | import com.google.firebase.storage.StorageReference; 6 | import io.reactivex.SingleEmitter; 7 | import io.reactivex.SingleOnSubscribe; 8 | 9 | final class GetMetadataOnSubscribe implements SingleOnSubscribe { 10 | 11 | private final StorageReference mRef; 12 | 13 | GetMetadataOnSubscribe(StorageReference ref) { 14 | this.mRef = ref; 15 | } 16 | 17 | @Override public void subscribe(SingleEmitter e) throws Exception { 18 | mRef.getMetadata().addOnCompleteListener(GmsTaskListeners.listener(e)); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /firebase-auth/src/main/java/com/github/b3er/rxfirebase/auth/UserUpdateEmailOnSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.auth; 2 | 3 | import com.github.b3er.rxfirebase.common.GmsTaskListeners; 4 | import com.google.firebase.auth.FirebaseUser; 5 | import io.reactivex.CompletableEmitter; 6 | import io.reactivex.CompletableOnSubscribe; 7 | 8 | final class UserUpdateEmailOnSubscribe implements CompletableOnSubscribe { 9 | 10 | private final FirebaseUser user; 11 | 12 | private final String email; 13 | 14 | UserUpdateEmailOnSubscribe(FirebaseUser user, String email) { 15 | this.user = user; 16 | this.email = email; 17 | } 18 | 19 | @Override public void subscribe(CompletableEmitter emitter) { 20 | user.updateEmail(email).addOnCompleteListener(GmsTaskListeners.listener(emitter)); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /firebase-auth/src/main/java/com/github/b3er/rxfirebase/auth/SignInWithEmailAndPasswordOnSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.auth; 2 | 3 | import com.google.android.gms.tasks.Task; 4 | import com.google.firebase.auth.AuthResult; 5 | import com.google.firebase.auth.FirebaseAuth; 6 | 7 | final class SignInWithEmailAndPasswordOnSubscribe extends BaseAuthOnSubscribe { 8 | 9 | private final String email; 10 | 11 | private final String password; 12 | 13 | SignInWithEmailAndPasswordOnSubscribe(FirebaseAuth instance, String email, String password) { 14 | super(instance); 15 | this.email = email; 16 | this.password = password; 17 | } 18 | 19 | @Override protected Task createAuthTask(FirebaseAuth instance) { 20 | return instance.signInWithEmailAndPassword(email, password); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /firebase-auth/src/main/java/com/github/b3er/rxfirebase/auth/CreateUserWithEmailAndPasswordOnSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.auth; 2 | 3 | import com.google.android.gms.tasks.Task; 4 | import com.google.firebase.auth.AuthResult; 5 | import com.google.firebase.auth.FirebaseAuth; 6 | 7 | class CreateUserWithEmailAndPasswordOnSubscribe extends BaseAuthOnSubscribe { 8 | 9 | private final String email; 10 | 11 | private final String password; 12 | 13 | CreateUserWithEmailAndPasswordOnSubscribe(FirebaseAuth instance, String email, String password) { 14 | super(instance); 15 | this.email = email; 16 | this.password = password; 17 | } 18 | 19 | @Override protected Task createAuthTask(FirebaseAuth instance) { 20 | return instance.createUserWithEmailAndPassword(email, password); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /firebase-auth/src/main/java/com/github/b3er/rxfirebase/auth/UserUpdatePasswordOnSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.auth; 2 | 3 | import com.github.b3er.rxfirebase.common.GmsTaskListeners; 4 | import com.google.firebase.auth.FirebaseUser; 5 | import io.reactivex.CompletableEmitter; 6 | import io.reactivex.CompletableOnSubscribe; 7 | 8 | final class UserUpdatePasswordOnSubscribe implements CompletableOnSubscribe { 9 | 10 | private final FirebaseUser user; 11 | 12 | private final String password; 13 | 14 | UserUpdatePasswordOnSubscribe(FirebaseUser user, String password) { 15 | this.user = user; 16 | this.password = password; 17 | } 18 | 19 | @Override public void subscribe(CompletableEmitter emitter) { 20 | user.updatePassword(password).addOnCompleteListener(GmsTaskListeners.listener(emitter)); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /firebase-database/src/main/java/com/github/b3er/rxfirebase/database/SetPriorityOnSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.database; 2 | 3 | import com.github.b3er.rxfirebase.common.GmsTaskListeners; 4 | import com.google.firebase.database.DatabaseReference; 5 | import io.reactivex.CompletableEmitter; 6 | import io.reactivex.CompletableOnSubscribe; 7 | 8 | final class SetPriorityOnSubscribe implements CompletableOnSubscribe { 9 | 10 | private final DatabaseReference ref; 11 | 12 | private final Object priority; 13 | 14 | SetPriorityOnSubscribe(DatabaseReference ref, Object priority) { 15 | this.ref = ref; 16 | this.priority = priority; 17 | } 18 | 19 | @Override public void subscribe(final CompletableEmitter emitter) { 20 | ref.setPriority(priority).addOnCompleteListener(GmsTaskListeners.listener(emitter)); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /firebase-storage/src/main/java/com/github/b3er/rxfirebase/storage/GetStreamOnSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.storage; 2 | 3 | import com.github.b3er.rxfirebase.common.GmsTaskListeners; 4 | import com.google.firebase.storage.StorageReference; 5 | import com.google.firebase.storage.StreamDownloadTask; 6 | import io.reactivex.SingleEmitter; 7 | import io.reactivex.SingleOnSubscribe; 8 | 9 | final class GetStreamOnSubscribe implements SingleOnSubscribe { 10 | 11 | private final StorageReference mRef; 12 | 13 | GetStreamOnSubscribe(StorageReference ref) { 14 | this.mRef = ref; 15 | } 16 | 17 | @Override public void subscribe(SingleEmitter e) 18 | throws Exception { 19 | mRef.getStream().addOnCompleteListener(GmsTaskListeners.listener(e)); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /firebase-auth/src/main/java/com/github/b3er/rxfirebase/auth/UserUnlinkOnSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.auth; 2 | 3 | import com.github.b3er.rxfirebase.common.GmsTaskListeners; 4 | import com.google.firebase.auth.AuthResult; 5 | import com.google.firebase.auth.FirebaseUser; 6 | import io.reactivex.SingleEmitter; 7 | import io.reactivex.SingleOnSubscribe; 8 | 9 | final class UserUnlinkOnSubscribe implements SingleOnSubscribe { 10 | 11 | private final FirebaseUser user; 12 | 13 | private final String provider; 14 | 15 | UserUnlinkOnSubscribe(FirebaseUser user, String provider) { 16 | this.user = user; 17 | this.provider = provider; 18 | } 19 | 20 | @Override public void subscribe(SingleEmitter emitter) { 21 | user.unlink(provider).addOnCompleteListener(GmsTaskListeners.listener(emitter)); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /firebase-auth/src/main/java/com/github/b3er/rxfirebase/auth/ApplyActionCodeOnSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.auth; 2 | 3 | import com.github.b3er.rxfirebase.common.GmsTaskListeners; 4 | import com.google.firebase.auth.FirebaseAuth; 5 | import io.reactivex.CompletableEmitter; 6 | import io.reactivex.CompletableOnSubscribe; 7 | 8 | final class ApplyActionCodeOnSubscribe implements CompletableOnSubscribe { 9 | private final FirebaseAuth instance; 10 | private final String code; 11 | 12 | ApplyActionCodeOnSubscribe(FirebaseAuth instance, String code) { 13 | this.instance = instance; 14 | this.code = code; 15 | } 16 | 17 | @Override public void subscribe(CompletableEmitter emitter) { 18 | if (!emitter.isDisposed()) { 19 | instance.applyActionCode(code).addOnCompleteListener(GmsTaskListeners.listener(emitter)); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /firebase-auth/src/main/java/com/github/b3er/rxfirebase/auth/SendPasswordResetEmailOnSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.auth; 2 | 3 | import com.github.b3er.rxfirebase.common.GmsTaskListeners; 4 | import com.google.firebase.auth.FirebaseAuth; 5 | import io.reactivex.CompletableEmitter; 6 | import io.reactivex.CompletableOnSubscribe; 7 | 8 | final class SendPasswordResetEmailOnSubscribe implements CompletableOnSubscribe { 9 | 10 | private final FirebaseAuth instance; 11 | 12 | private final String email; 13 | 14 | SendPasswordResetEmailOnSubscribe(FirebaseAuth instance, String email) { 15 | this.instance = instance; 16 | this.email = email; 17 | } 18 | 19 | @Override public void subscribe(final CompletableEmitter emitter) { 20 | instance.sendPasswordResetEmail(email) 21 | .addOnCompleteListener(GmsTaskListeners.listener(emitter)); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /firebase-storage/src/main/java/com/github/b3er/rxfirebase/storage/PutBytesOnSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.storage; 2 | 3 | import com.github.b3er.rxfirebase.common.GmsTaskListeners; 4 | import com.google.firebase.storage.StorageReference; 5 | import com.google.firebase.storage.UploadTask; 6 | import io.reactivex.SingleEmitter; 7 | import io.reactivex.SingleOnSubscribe; 8 | 9 | final class PutBytesOnSubscribe implements SingleOnSubscribe { 10 | 11 | private final StorageReference mRef; 12 | 13 | private final byte[] mBytes; 14 | 15 | PutBytesOnSubscribe(StorageReference ref, byte[] bytes) { 16 | mRef = ref; 17 | mBytes = bytes; 18 | } 19 | 20 | @Override public void subscribe(SingleEmitter e) throws Exception { 21 | mRef.putBytes(mBytes).addOnCompleteListener(GmsTaskListeners.listener(e)); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /firebase-database/src/main/java/com/github/b3er/rxfirebase/database/UpdateChildrenOnSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.database; 2 | 3 | import com.github.b3er.rxfirebase.common.GmsTaskListeners; 4 | import com.google.firebase.database.DatabaseReference; 5 | import io.reactivex.CompletableEmitter; 6 | import io.reactivex.CompletableOnSubscribe; 7 | import java.util.Map; 8 | 9 | final class UpdateChildrenOnSubscribe implements CompletableOnSubscribe { 10 | 11 | private final DatabaseReference ref; 12 | 13 | private final Map update; 14 | 15 | UpdateChildrenOnSubscribe(DatabaseReference ref, Map update) { 16 | this.ref = ref; 17 | this.update = update; 18 | } 19 | 20 | @Override public void subscribe(CompletableEmitter emitter) { 21 | ref.updateChildren(update).addOnCompleteListener(GmsTaskListeners.listener(emitter)); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /firebase-auth/src/main/java/com/github/b3er/rxfirebase/auth/GetCurrentUserOnSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.auth; 2 | 3 | import com.google.firebase.auth.FirebaseAuth; 4 | import com.google.firebase.auth.FirebaseUser; 5 | import io.reactivex.MaybeEmitter; 6 | import io.reactivex.MaybeOnSubscribe; 7 | 8 | final class GetCurrentUserOnSubscribe implements MaybeOnSubscribe { 9 | 10 | private FirebaseAuth instance; 11 | 12 | GetCurrentUserOnSubscribe(FirebaseAuth instance) { 13 | this.instance = instance; 14 | } 15 | 16 | @Override public void subscribe(MaybeEmitter emitter) { 17 | if (!emitter.isDisposed()) { 18 | FirebaseUser currentUser = instance.getCurrentUser(); 19 | if (currentUser != null) { 20 | emitter.onSuccess(currentUser); 21 | } else { 22 | emitter.onComplete(); 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /firebase-storage/src/main/java/com/github/b3er/rxfirebase/storage/PutFileOnSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.storage; 2 | 3 | import android.net.Uri; 4 | import com.github.b3er.rxfirebase.common.GmsTaskListeners; 5 | import com.google.firebase.storage.StorageReference; 6 | import com.google.firebase.storage.UploadTask; 7 | import io.reactivex.SingleEmitter; 8 | import io.reactivex.SingleOnSubscribe; 9 | 10 | final class PutFileOnSubscribe implements SingleOnSubscribe { 11 | 12 | private final StorageReference mRef; 13 | 14 | private final Uri mUri; 15 | 16 | PutFileOnSubscribe(StorageReference ref, Uri uri) { 17 | mRef = ref; 18 | mUri = uri; 19 | } 20 | 21 | @Override public void subscribe(SingleEmitter e) throws Exception { 22 | mRef.putFile(mUri).addOnCompleteListener(GmsTaskListeners.listener(e)); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /firebase-storage/src/main/java/com/github/b3er/rxfirebase/storage/GetBytesOnSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.storage; 2 | 3 | import com.github.b3er.rxfirebase.common.GmsTaskListeners; 4 | import com.google.firebase.storage.StorageReference; 5 | import io.reactivex.SingleEmitter; 6 | import io.reactivex.SingleOnSubscribe; 7 | 8 | final class GetBytesOnSubscribe implements SingleOnSubscribe { 9 | 10 | private final StorageReference mRef; 11 | 12 | private final long mMaxDownloadSizeBytes; 13 | 14 | GetBytesOnSubscribe(StorageReference ref, long maxDownloadSizeBytes) { 15 | this.mRef = ref; 16 | this.mMaxDownloadSizeBytes = maxDownloadSizeBytes; 17 | } 18 | 19 | @Override public void subscribe(final SingleEmitter emitter) throws Exception { 20 | mRef.getBytes(mMaxDownloadSizeBytes).addOnCompleteListener(GmsTaskListeners.listener(emitter)); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /firebase-auth/src/main/java/com/github/b3er/rxfirebase/auth/VerifyPasswordResetCodeOnSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.auth; 2 | 3 | import com.github.b3er.rxfirebase.common.GmsTaskListeners; 4 | import com.google.firebase.auth.FirebaseAuth; 5 | import io.reactivex.SingleEmitter; 6 | import io.reactivex.SingleOnSubscribe; 7 | 8 | final class VerifyPasswordResetCodeOnSubscribe implements SingleOnSubscribe { 9 | private final FirebaseAuth instance; 10 | private final String code; 11 | 12 | VerifyPasswordResetCodeOnSubscribe(FirebaseAuth instance, String code) { 13 | this.instance = instance; 14 | this.code = code; 15 | } 16 | 17 | @Override public void subscribe(SingleEmitter emitter) { 18 | if (!emitter.isDisposed()) { 19 | instance.verifyPasswordResetCode(code) 20 | .addOnCompleteListener(GmsTaskListeners.listener(emitter)); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /firebase-auth/src/main/java/com/github/b3er/rxfirebase/auth/UserReauthenticateOnSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.auth; 2 | 3 | import com.github.b3er.rxfirebase.common.GmsTaskListeners; 4 | import com.google.firebase.auth.AuthCredential; 5 | import com.google.firebase.auth.FirebaseUser; 6 | import io.reactivex.CompletableEmitter; 7 | import io.reactivex.CompletableOnSubscribe; 8 | 9 | final class UserReauthenticateOnSubscribe implements CompletableOnSubscribe { 10 | 11 | private final FirebaseUser user; 12 | 13 | private final AuthCredential credential; 14 | 15 | UserReauthenticateOnSubscribe(FirebaseUser user, AuthCredential credential) { 16 | this.user = user; 17 | this.credential = credential; 18 | } 19 | 20 | @Override public void subscribe(CompletableEmitter emitter) { 21 | user.reauthenticate(credential).addOnCompleteListener(GmsTaskListeners.listener(emitter)); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /firebase-auth/src/main/java/com/github/b3er/rxfirebase/auth/UserUpdateProfileOnSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.auth; 2 | 3 | import com.github.b3er.rxfirebase.common.GmsTaskListeners; 4 | import com.google.firebase.auth.FirebaseUser; 5 | import com.google.firebase.auth.UserProfileChangeRequest; 6 | import io.reactivex.CompletableEmitter; 7 | import io.reactivex.CompletableOnSubscribe; 8 | 9 | final class UserUpdateProfileOnSubscribe implements CompletableOnSubscribe { 10 | 11 | private final FirebaseUser user; 12 | 13 | private final UserProfileChangeRequest request; 14 | 15 | UserUpdateProfileOnSubscribe(FirebaseUser user, UserProfileChangeRequest request) { 16 | this.user = user; 17 | this.request = request; 18 | } 19 | 20 | @Override public void subscribe(final CompletableEmitter emitter) { 21 | user.updateProfile(request).addOnCompleteListener(GmsTaskListeners.listener(emitter)); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /firebase-database/src/main/java/com/github/b3er/rxfirebase/database/ChildEvent.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.database; 2 | 3 | import android.support.annotation.NonNull; 4 | import com.google.firebase.database.DataSnapshot; 5 | 6 | public abstract class ChildEvent { 7 | 8 | final DataSnapshot dataSnapshot; 9 | 10 | ChildEvent(DataSnapshot dataSnapshot) { 11 | this.dataSnapshot = dataSnapshot; 12 | } 13 | 14 | @NonNull public DataSnapshot dataSnapshot() { 15 | return dataSnapshot; 16 | } 17 | 18 | @Override public boolean equals(Object o) { 19 | if (this == o) { 20 | return true; 21 | } 22 | if (o == null || getClass() != o.getClass()) { 23 | return false; 24 | } 25 | 26 | ChildEvent that = (ChildEvent) o; 27 | 28 | return dataSnapshot.equals(that.dataSnapshot); 29 | } 30 | 31 | @Override public int hashCode() { 32 | return dataSnapshot.hashCode(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /firebase-storage/src/main/java/com/github/b3er/rxfirebase/storage/UpdateMetadataOnSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.storage; 2 | 3 | import com.github.b3er.rxfirebase.common.GmsTaskListeners; 4 | import com.google.firebase.storage.StorageMetadata; 5 | import com.google.firebase.storage.StorageReference; 6 | import io.reactivex.SingleEmitter; 7 | import io.reactivex.SingleOnSubscribe; 8 | 9 | final class UpdateMetadataOnSubscribe implements SingleOnSubscribe { 10 | 11 | private final StorageReference mRef; 12 | 13 | private final StorageMetadata mMetadata; 14 | 15 | UpdateMetadataOnSubscribe(StorageReference ref, StorageMetadata metadata) { 16 | mRef = ref; 17 | mMetadata = metadata; 18 | } 19 | 20 | @Override public void subscribe(SingleEmitter e) throws Exception { 21 | mRef.updateMetadata(mMetadata).addOnCompleteListener(GmsTaskListeners.listener(e)); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /firebase-auth/src/main/java/com/github/b3er/rxfirebase/auth/CheckActionCodeOnSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.auth; 2 | 3 | import com.github.b3er.rxfirebase.common.GmsTaskListeners; 4 | import com.google.firebase.auth.ActionCodeResult; 5 | import com.google.firebase.auth.FirebaseAuth; 6 | import io.reactivex.SingleEmitter; 7 | import io.reactivex.SingleOnSubscribe; 8 | 9 | final class CheckActionCodeOnSubscribe implements SingleOnSubscribe { 10 | private final FirebaseAuth instance; 11 | private final String code; 12 | 13 | CheckActionCodeOnSubscribe(FirebaseAuth instance, String code) { 14 | this.instance = instance; 15 | this.code = code; 16 | } 17 | 18 | @Override public void subscribe(SingleEmitter emitter) { 19 | if (!emitter.isDisposed()) { 20 | instance.checkActionCode(code).addOnCompleteListener(GmsTaskListeners.listener(emitter)); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /firebase-database/src/main/java/com/github/b3er/rxfirebase/database/SetValueWithPriorityOnSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.database; 2 | 3 | import com.github.b3er.rxfirebase.common.GmsTaskListeners; 4 | import com.google.firebase.database.DatabaseReference; 5 | import io.reactivex.CompletableEmitter; 6 | import io.reactivex.CompletableOnSubscribe; 7 | 8 | final class SetValueWithPriorityOnSubscribe implements CompletableOnSubscribe { 9 | 10 | private final DatabaseReference ref; 11 | 12 | private final T value; 13 | 14 | private final Object priority; 15 | 16 | SetValueWithPriorityOnSubscribe(DatabaseReference ref, T value, Object priority) { 17 | this.ref = ref; 18 | this.value = value; 19 | this.priority = priority; 20 | } 21 | 22 | @Override public void subscribe(CompletableEmitter emitter) { 23 | ref.setValue(value, priority).addOnCompleteListener(GmsTaskListeners.listener(emitter)); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /firebase-storage/src/main/java/com/github/b3er/rxfirebase/storage/GetFileToFileOnSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.storage; 2 | 3 | import com.github.b3er.rxfirebase.common.GmsTaskListeners; 4 | import com.google.firebase.storage.FileDownloadTask; 5 | import com.google.firebase.storage.StorageReference; 6 | import io.reactivex.SingleEmitter; 7 | import io.reactivex.SingleOnSubscribe; 8 | import java.io.File; 9 | 10 | final class GetFileToFileOnSubscribe implements SingleOnSubscribe { 11 | 12 | private final StorageReference mRef; 13 | 14 | private final File mFile; 15 | 16 | GetFileToFileOnSubscribe(StorageReference ref, File file) { 17 | this.mRef = ref; 18 | this.mFile = file; 19 | } 20 | 21 | @Override public void subscribe(SingleEmitter e) throws Exception { 22 | mRef.getFile(mFile).addOnCompleteListener(GmsTaskListeners.listener(e)); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /firebase-storage/src/main/java/com/github/b3er/rxfirebase/storage/GetFileToUriOnSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.storage; 2 | 3 | import android.net.Uri; 4 | import com.github.b3er.rxfirebase.common.GmsTaskListeners; 5 | import com.google.firebase.storage.FileDownloadTask; 6 | import com.google.firebase.storage.StorageReference; 7 | import io.reactivex.SingleEmitter; 8 | import io.reactivex.SingleOnSubscribe; 9 | 10 | final class GetFileToUriOnSubscribe implements SingleOnSubscribe { 11 | 12 | private final StorageReference reference; 13 | 14 | private final Uri uri; 15 | 16 | GetFileToUriOnSubscribe(StorageReference ref, Uri uri) { 17 | this.reference = ref; 18 | this.uri = uri; 19 | } 20 | 21 | @Override public void subscribe(SingleEmitter e) throws Exception { 22 | reference.getFile(uri).addOnCompleteListener(GmsTaskListeners.listener(e)); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /firebase-storage/src/main/java/com/github/b3er/rxfirebase/storage/PutStreamOnSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.storage; 2 | 3 | import com.github.b3er.rxfirebase.common.GmsTaskListeners; 4 | import com.google.firebase.storage.StorageReference; 5 | import com.google.firebase.storage.UploadTask; 6 | import io.reactivex.SingleEmitter; 7 | import io.reactivex.SingleOnSubscribe; 8 | import java.io.InputStream; 9 | 10 | final class PutStreamOnSubscribe implements SingleOnSubscribe { 11 | 12 | private final StorageReference mRef; 13 | 14 | private final InputStream mInputStream; 15 | 16 | PutStreamOnSubscribe(StorageReference ref, InputStream inputStream) { 17 | 18 | mRef = ref; 19 | mInputStream = inputStream; 20 | } 21 | 22 | @Override public void subscribe(SingleEmitter e) throws Exception { 23 | mRef.putStream(mInputStream).addOnCompleteListener(GmsTaskListeners.listener(e)); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /firebase-auth/src/main/java/com/github/b3er/rxfirebase/auth/UserLinkWithCredentialOnSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.auth; 2 | 3 | import com.github.b3er.rxfirebase.common.GmsTaskListeners; 4 | import com.google.firebase.auth.AuthCredential; 5 | import com.google.firebase.auth.AuthResult; 6 | import com.google.firebase.auth.FirebaseUser; 7 | import io.reactivex.SingleEmitter; 8 | import io.reactivex.SingleOnSubscribe; 9 | 10 | final class UserLinkWithCredentialOnSubscribe implements SingleOnSubscribe { 11 | 12 | private final FirebaseUser user; 13 | 14 | private final AuthCredential credential; 15 | 16 | UserLinkWithCredentialOnSubscribe(FirebaseUser user, AuthCredential credential) { 17 | this.user = user; 18 | this.credential = credential; 19 | } 20 | 21 | @Override public void subscribe(SingleEmitter emitter) { 22 | user.linkWithCredential(credential).addOnCompleteListener(GmsTaskListeners.listener(emitter)); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /firebase-auth/src/main/java/com/github/b3er/rxfirebase/auth/ConfirmPasswordResetOnSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.auth; 2 | 3 | import com.github.b3er.rxfirebase.common.GmsTaskListeners; 4 | import com.google.firebase.auth.FirebaseAuth; 5 | import io.reactivex.CompletableEmitter; 6 | import io.reactivex.CompletableOnSubscribe; 7 | 8 | final class ConfirmPasswordResetOnSubscribe implements CompletableOnSubscribe { 9 | private final FirebaseAuth instance; 10 | private final String code; 11 | private final String newPassword; 12 | 13 | ConfirmPasswordResetOnSubscribe(FirebaseAuth instance, String code, String newPassword) { 14 | this.instance = instance; 15 | this.code = code; 16 | this.newPassword = newPassword; 17 | } 18 | 19 | @Override public void subscribe(CompletableEmitter emitter) { 20 | if (!emitter.isDisposed()) { 21 | instance.confirmPasswordReset(code, newPassword) 22 | .addOnCompleteListener(GmsTaskListeners.listener(emitter)); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /firebase-database/src/main/java/com/github/b3er/rxfirebase/database/transformers/SingleTransformerOfClazz.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.database.transformers; 2 | 3 | import com.google.firebase.database.DataSnapshot; 4 | import com.memoizrlabs.retrooptional.Optional; 5 | import io.reactivex.Single; 6 | import io.reactivex.SingleSource; 7 | import io.reactivex.SingleTransformer; 8 | import io.reactivex.functions.Function; 9 | 10 | public final class SingleTransformerOfClazz 11 | implements SingleTransformer> { 12 | 13 | private final Class clazz; 14 | 15 | public SingleTransformerOfClazz(Class clazz) { 16 | this.clazz = clazz; 17 | } 18 | 19 | @Override public SingleSource> apply(Single upstream) { 20 | return upstream.map(new Function>() { 21 | @Override public Optional apply(DataSnapshot dataSnapshot) throws Exception { 22 | return Optional.of(dataSnapshot.getValue(clazz)); 23 | } 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /firebase-database/src/main/java/com/github/b3er/rxfirebase/database/transformers/ObsTransformerOfClazz.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.database.transformers; 2 | 3 | import com.google.firebase.database.DataSnapshot; 4 | import com.memoizrlabs.retrooptional.Optional; 5 | import io.reactivex.Observable; 6 | import io.reactivex.ObservableSource; 7 | import io.reactivex.ObservableTransformer; 8 | import io.reactivex.functions.Function; 9 | 10 | public final class ObsTransformerOfClazz 11 | implements ObservableTransformer> { 12 | 13 | private final Class clazz; 14 | 15 | public ObsTransformerOfClazz(Class clazz) { 16 | this.clazz = clazz; 17 | } 18 | 19 | @Override public ObservableSource> apply(Observable upstream) { 20 | return upstream.map(new Function>() { 21 | @Override public Optional apply(DataSnapshot dataSnapshot) throws Exception { 22 | return Optional.of(dataSnapshot.getValue(clazz)); 23 | } 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /common/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "com.github.b3er.local.properties" version "1.1" 3 | } 4 | apply plugin: 'com.android.library' 5 | 6 | android { 7 | compileSdkVersion rootProject.ext.compileSdkVersion 8 | buildToolsVersion rootProject.ext.buildToolsVersion 9 | 10 | defaultConfig { 11 | minSdkVersion rootProject.ext.minSdkVersion 12 | } 13 | 14 | compileOptions { 15 | sourceCompatibility JavaVersion.VERSION_1_7 16 | targetCompatibility JavaVersion.VERSION_1_7 17 | } 18 | 19 | dexOptions { 20 | preDexLibraries = !rootProject.ext.ci 21 | } 22 | 23 | lintOptions { 24 | textReport true 25 | textOutput 'stdout' 26 | } 27 | 28 | buildTypes { 29 | release { 30 | minifyEnabled false 31 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 32 | } 33 | } 34 | } 35 | 36 | dependencies { 37 | compile rootProject.ext.rxJava 38 | compile rootProject.ext.supportAnnotations 39 | compile rootProject.ext.firebaseCommon 40 | } 41 | 42 | apply from: rootProject.file('gradle/gradle-mvn-push.gradle') 43 | -------------------------------------------------------------------------------- /firebase-storage/src/main/java/com/github/b3er/rxfirebase/storage/GetStreamWithProcessorOnSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.storage; 2 | 3 | import com.github.b3er.rxfirebase.common.GmsTaskListeners; 4 | import com.google.firebase.storage.StorageReference; 5 | import com.google.firebase.storage.StreamDownloadTask; 6 | import io.reactivex.SingleEmitter; 7 | import io.reactivex.SingleOnSubscribe; 8 | 9 | final class GetStreamWithProcessorOnSubscribe 10 | implements SingleOnSubscribe { 11 | 12 | private final StorageReference mRef; 13 | 14 | private final StreamDownloadTask.StreamProcessor mStreamProcessor; 15 | 16 | GetStreamWithProcessorOnSubscribe(StorageReference ref, 17 | StreamDownloadTask.StreamProcessor streamProcessor) { 18 | this.mRef = ref; 19 | this.mStreamProcessor = streamProcessor; 20 | } 21 | 22 | @Override public void subscribe(SingleEmitter e) 23 | throws Exception { 24 | mRef.getStream(mStreamProcessor).addOnCompleteListener(GmsTaskListeners.listener(e)); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /dependencies.gradle: -------------------------------------------------------------------------------- 1 | ext { 2 | // Build SDK versions 3 | buildToolsVersion = '25.0.2' 4 | kotlinVersion = '1.1.2' 5 | minSdkVersion = 14 6 | compileSdkVersion = 25 7 | 8 | // CI 9 | ci = 'true'.equals(System.getenv('CI')) 10 | 11 | // Firebase Version 12 | firebaseVersion = '11.0.2' 13 | 14 | // Dependencies 15 | assertj = 'org.assertj:assertj-core:1.2.0' 16 | firebaseCommon = "com.google.firebase:firebase-common:${firebaseVersion}" 17 | firebaseAuth = "com.google.firebase:firebase-auth:${firebaseVersion}" 18 | firebaseCore = "com.google.firebase:firebase-core:${firebaseVersion}" 19 | firebaseDatabase = "com.google.firebase:firebase-database:${firebaseVersion}" 20 | firebaseStorage = "com.google.firebase:firebase-storage:${firebaseVersion}" 21 | junit = 'junit:junit:4.12' 22 | kotlin = "org.jetbrains.kotlin:kotlin-stdlib-jre7:${kotlinVersion}" 23 | mockito = 'org.mockito:mockito-core:2.7.19' 24 | retroOptional = 'com.github.memoizr:retro-optional:0.2.0' 25 | rxJava = 'io.reactivex.rxjava2:rxjava:2.1.1' 26 | supportAnnotations = 'com.android.support:support-annotations:25.1.0' 27 | } -------------------------------------------------------------------------------- /firebase-storage/src/main/java/com/github/b3er/rxfirebase/storage/PutBytesWithMetadataOnSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.storage; 2 | 3 | import com.github.b3er.rxfirebase.common.GmsTaskListeners; 4 | import com.google.firebase.storage.StorageMetadata; 5 | import com.google.firebase.storage.StorageReference; 6 | import com.google.firebase.storage.UploadTask; 7 | import io.reactivex.SingleEmitter; 8 | import io.reactivex.SingleOnSubscribe; 9 | 10 | final class PutBytesWithMetadataOnSubscribe implements SingleOnSubscribe { 11 | 12 | private final StorageReference mRef; 13 | 14 | private final StorageMetadata mStorageMetadata; 15 | 16 | private byte[] mBytes; 17 | 18 | PutBytesWithMetadataOnSubscribe(StorageReference ref, byte[] bytes, 19 | StorageMetadata storageMetadata) { 20 | mRef = ref; 21 | mBytes = bytes; 22 | mStorageMetadata = storageMetadata; 23 | } 24 | 25 | @Override public void subscribe(SingleEmitter e) throws Exception { 26 | mRef.putBytes(mBytes, mStorageMetadata).addOnCompleteListener(GmsTaskListeners.listener(e)); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /firebase-storage/src/main/java/com/github/b3er/rxfirebase/storage/PutFileWithMetadataOnSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.storage; 2 | 3 | import android.net.Uri; 4 | import com.github.b3er.rxfirebase.common.GmsTaskListeners; 5 | import com.google.firebase.storage.StorageMetadata; 6 | import com.google.firebase.storage.StorageReference; 7 | import com.google.firebase.storage.UploadTask; 8 | import io.reactivex.SingleEmitter; 9 | import io.reactivex.SingleOnSubscribe; 10 | 11 | final class PutFileWithMetadataOnSubscribe implements SingleOnSubscribe { 12 | 13 | private final StorageReference mRef; 14 | 15 | private final Uri mUri; 16 | 17 | private StorageMetadata mStorageMetadata; 18 | 19 | PutFileWithMetadataOnSubscribe(StorageReference ref, Uri uri, StorageMetadata storageMetadata) { 20 | mRef = ref; 21 | mUri = uri; 22 | mStorageMetadata = storageMetadata; 23 | } 24 | 25 | @Override public void subscribe(SingleEmitter e) throws Exception { 26 | mRef.putFile(mUri, mStorageMetadata).addOnCompleteListener(GmsTaskListeners.listener(e)); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /firebase-auth-kotlin/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "com.github.b3er.local.properties" version "1.1" 3 | } 4 | apply plugin: 'com.android.library' 5 | apply plugin: 'kotlin-android' 6 | 7 | android { 8 | compileSdkVersion rootProject.ext.compileSdkVersion 9 | buildToolsVersion rootProject.ext.buildToolsVersion 10 | 11 | defaultConfig { 12 | minSdkVersion rootProject.ext.minSdkVersion 13 | } 14 | 15 | compileOptions { 16 | sourceCompatibility JavaVersion.VERSION_1_7 17 | targetCompatibility JavaVersion.VERSION_1_7 18 | } 19 | 20 | dexOptions { 21 | preDexLibraries = !rootProject.ext.ci 22 | } 23 | 24 | lintOptions { 25 | textReport true 26 | textOutput 'stdout' 27 | } 28 | 29 | sourceSets { 30 | main.java.srcDirs += 'src/main/kotlin' 31 | } 32 | 33 | buildTypes { 34 | release { 35 | minifyEnabled false 36 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 37 | } 38 | } 39 | } 40 | 41 | dependencies { 42 | compile project(':common') 43 | compile project(':firebase-auth') 44 | 45 | compile rootProject.ext.kotlin 46 | } 47 | 48 | apply from: rootProject.file('gradle/gradle-mvn-push.gradle') 49 | -------------------------------------------------------------------------------- /firebase-database/src/main/java/com/github/b3er/rxfirebase/database/transformers/SingleTransformerOfGenericTypeIndicator.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.database.transformers; 2 | 3 | import com.google.firebase.database.DataSnapshot; 4 | import com.google.firebase.database.GenericTypeIndicator; 5 | import com.memoizrlabs.retrooptional.Optional; 6 | import io.reactivex.Single; 7 | import io.reactivex.SingleSource; 8 | import io.reactivex.SingleTransformer; 9 | import io.reactivex.functions.Function; 10 | 11 | public final class SingleTransformerOfGenericTypeIndicator 12 | implements SingleTransformer> { 13 | 14 | private GenericTypeIndicator typeIndicator; 15 | 16 | public SingleTransformerOfGenericTypeIndicator(GenericTypeIndicator indicator) { 17 | this.typeIndicator = indicator; 18 | } 19 | 20 | @Override public SingleSource> apply(Single upstream) { 21 | return upstream.map(new Function>() { 22 | @Override public Optional apply(DataSnapshot dataSnapshot) throws Exception { 23 | return Optional.of(dataSnapshot.getValue(typeIndicator)); 24 | } 25 | }); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /firebase-storage-kotlin/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "com.github.b3er.local.properties" version "1.1" 3 | } 4 | apply plugin: 'com.android.library' 5 | apply plugin: 'kotlin-android' 6 | 7 | android { 8 | compileSdkVersion rootProject.ext.compileSdkVersion 9 | buildToolsVersion rootProject.ext.buildToolsVersion 10 | 11 | defaultConfig { 12 | minSdkVersion rootProject.ext.minSdkVersion 13 | } 14 | 15 | compileOptions { 16 | sourceCompatibility JavaVersion.VERSION_1_7 17 | targetCompatibility JavaVersion.VERSION_1_7 18 | } 19 | 20 | dexOptions { 21 | preDexLibraries = !rootProject.ext.ci 22 | } 23 | 24 | lintOptions { 25 | textReport true 26 | textOutput 'stdout' 27 | } 28 | 29 | sourceSets { 30 | main.java.srcDirs += 'src/main/kotlin' 31 | } 32 | 33 | buildTypes { 34 | release { 35 | minifyEnabled false 36 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 37 | } 38 | } 39 | } 40 | 41 | dependencies { 42 | compile project(':common') 43 | compile project(':firebase-storage') 44 | compile rootProject.ext.kotlin 45 | } 46 | 47 | apply from: rootProject.file('gradle/gradle-mvn-push.gradle') 48 | -------------------------------------------------------------------------------- /firebase-database-kotlin/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "com.github.b3er.local.properties" version "1.1" 3 | } 4 | apply plugin: 'com.android.library' 5 | apply plugin: 'kotlin-android' 6 | 7 | android { 8 | compileSdkVersion rootProject.ext.compileSdkVersion 9 | buildToolsVersion rootProject.ext.buildToolsVersion 10 | 11 | defaultConfig { 12 | minSdkVersion rootProject.ext.minSdkVersion 13 | } 14 | 15 | compileOptions { 16 | sourceCompatibility JavaVersion.VERSION_1_7 17 | targetCompatibility JavaVersion.VERSION_1_7 18 | } 19 | 20 | dexOptions { 21 | preDexLibraries = !rootProject.ext.ci 22 | } 23 | 24 | lintOptions { 25 | textReport true 26 | textOutput 'stdout' 27 | } 28 | 29 | sourceSets { 30 | main.java.srcDirs += 'src/main/kotlin' 31 | } 32 | 33 | buildTypes { 34 | release { 35 | minifyEnabled false 36 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 37 | } 38 | } 39 | } 40 | 41 | dependencies { 42 | compile project(':common') 43 | compile project(':firebase-database') 44 | 45 | compile rootProject.ext.kotlin 46 | } 47 | 48 | apply from: rootProject.file('gradle/gradle-mvn-push.gradle') 49 | -------------------------------------------------------------------------------- /firebase-database/src/main/java/com/github/b3er/rxfirebase/database/transformers/ObsTransformerOfGenericTypeIndicator.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.database.transformers; 2 | 3 | import com.google.firebase.database.DataSnapshot; 4 | import com.google.firebase.database.GenericTypeIndicator; 5 | import com.memoizrlabs.retrooptional.Optional; 6 | import io.reactivex.Observable; 7 | import io.reactivex.ObservableSource; 8 | import io.reactivex.ObservableTransformer; 9 | import io.reactivex.functions.Function; 10 | 11 | public final class ObsTransformerOfGenericTypeIndicator 12 | implements ObservableTransformer> { 13 | 14 | private GenericTypeIndicator typeIndicator; 15 | 16 | public ObsTransformerOfGenericTypeIndicator(GenericTypeIndicator indicator) { 17 | this.typeIndicator = indicator; 18 | } 19 | 20 | @Override public ObservableSource> apply(Observable upstream) { 21 | return upstream.map(new Function>() { 22 | @Override public Optional apply(DataSnapshot dataSnapshot) throws Exception { 23 | return Optional.of(dataSnapshot.getValue(typeIndicator)); 24 | } 25 | }); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /firebase-storage/src/main/java/com/github/b3er/rxfirebase/storage/PutStreamWithMetadataOnSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.storage; 2 | 3 | import com.github.b3er.rxfirebase.common.GmsTaskListeners; 4 | import com.google.firebase.storage.StorageMetadata; 5 | import com.google.firebase.storage.StorageReference; 6 | import com.google.firebase.storage.UploadTask; 7 | import io.reactivex.SingleEmitter; 8 | import io.reactivex.SingleOnSubscribe; 9 | import java.io.InputStream; 10 | 11 | final class PutStreamWithMetadataOnSubscribe implements SingleOnSubscribe { 12 | 13 | private final StorageReference mRef; 14 | 15 | private final InputStream mInputStream; 16 | 17 | private final StorageMetadata mStorageMetadata; 18 | 19 | PutStreamWithMetadataOnSubscribe(StorageReference ref, InputStream inputStream, 20 | StorageMetadata storageMetadata) { 21 | mRef = ref; 22 | mInputStream = inputStream; 23 | mStorageMetadata = storageMetadata; 24 | } 25 | 26 | @Override public void subscribe(SingleEmitter e) throws Exception { 27 | mRef.putStream(mInputStream, mStorageMetadata) 28 | .addOnCompleteListener(GmsTaskListeners.listener(e)); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /firebase-database/src/main/java/com/github/b3er/rxfirebase/database/DataOnSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.database; 2 | 3 | import com.google.firebase.database.DataSnapshot; 4 | import com.google.firebase.database.DatabaseError; 5 | import com.google.firebase.database.DatabaseReference; 6 | import com.google.firebase.database.ValueEventListener; 7 | import io.reactivex.SingleEmitter; 8 | import io.reactivex.SingleOnSubscribe; 9 | 10 | final class DataOnSubscribe implements SingleOnSubscribe { 11 | 12 | private final DatabaseReference ref; 13 | 14 | DataOnSubscribe(DatabaseReference ref) { 15 | this.ref = ref; 16 | } 17 | 18 | @Override public void subscribe(final SingleEmitter emitter) { 19 | final ValueEventListener listener = new ValueEventListener() { 20 | @Override public void onDataChange(DataSnapshot dataSnapshot) { 21 | if (!emitter.isDisposed()) { 22 | emitter.onSuccess(dataSnapshot); 23 | } 24 | } 25 | 26 | @Override public void onCancelled(DatabaseError databaseError) { 27 | if (!emitter.isDisposed()) { 28 | emitter.onError(databaseError.toException()); 29 | } 30 | } 31 | }; 32 | 33 | ref.addListenerForSingleValueEvent(listener); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /firebase-auth/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "com.github.b3er.local.properties" version "1.1" 3 | } 4 | apply plugin: 'com.android.library' 5 | 6 | android { 7 | compileSdkVersion rootProject.ext.compileSdkVersion 8 | buildToolsVersion rootProject.ext.buildToolsVersion 9 | 10 | defaultConfig { 11 | minSdkVersion rootProject.ext.minSdkVersion 12 | } 13 | 14 | compileOptions { 15 | sourceCompatibility JavaVersion.VERSION_1_7 16 | targetCompatibility JavaVersion.VERSION_1_7 17 | } 18 | 19 | dexOptions { 20 | preDexLibraries = !rootProject.ext.ci 21 | } 22 | 23 | lintOptions { 24 | textReport true 25 | textOutput 'stdout' 26 | } 27 | 28 | buildTypes { 29 | release { 30 | minifyEnabled false 31 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 32 | } 33 | } 34 | } 35 | 36 | dependencies { 37 | compile project(':common') 38 | 39 | compile rootProject.ext.firebaseAuth 40 | 41 | testCompile rootProject.ext.assertj 42 | testCompile rootProject.ext.junit 43 | testCompile rootProject.ext.mockito 44 | } 45 | 46 | apply plugin: 'com.github.kt3k.coveralls' 47 | 48 | coveralls { 49 | jacocoReportPath = "${buildDir}/reports/coverageReport/coverageReport.xml" 50 | } 51 | 52 | apply from: rootProject.file('gradle/gradle-mvn-push.gradle') 53 | -------------------------------------------------------------------------------- /firebase-auth/src/main/java/com/github/b3er/rxfirebase/auth/AuthStateChangesOnSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.auth; 2 | 3 | import android.support.annotation.NonNull; 4 | import com.google.firebase.auth.FirebaseAuth; 5 | import io.reactivex.ObservableEmitter; 6 | import io.reactivex.ObservableOnSubscribe; 7 | import io.reactivex.disposables.Disposables; 8 | import io.reactivex.functions.Action; 9 | 10 | final class AuthStateChangesOnSubscribe implements ObservableOnSubscribe { 11 | 12 | private final FirebaseAuth instance; 13 | 14 | AuthStateChangesOnSubscribe(FirebaseAuth instance) { 15 | this.instance = instance; 16 | } 17 | 18 | @Override public void subscribe(final ObservableEmitter emitter) { 19 | final FirebaseAuth.AuthStateListener listener = new FirebaseAuth.AuthStateListener() { 20 | @Override public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) { 21 | if (!emitter.isDisposed()) { 22 | emitter.onNext(firebaseAuth); 23 | } 24 | } 25 | }; 26 | 27 | instance.addAuthStateListener(listener); 28 | 29 | emitter.setDisposable(Disposables.fromAction(new Action() { 30 | @Override public void run() throws Exception { 31 | instance.removeAuthStateListener(listener); 32 | } 33 | })); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /firebase-storage/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "com.github.b3er.local.properties" version "1.1" 3 | } 4 | apply plugin: 'com.android.library' 5 | 6 | android { 7 | compileSdkVersion rootProject.ext.compileSdkVersion 8 | buildToolsVersion rootProject.ext.buildToolsVersion 9 | 10 | defaultConfig { 11 | minSdkVersion rootProject.ext.minSdkVersion 12 | } 13 | 14 | compileOptions { 15 | sourceCompatibility JavaVersion.VERSION_1_7 16 | targetCompatibility JavaVersion.VERSION_1_7 17 | } 18 | 19 | dexOptions { 20 | preDexLibraries = !rootProject.ext.ci 21 | } 22 | 23 | lintOptions { 24 | textReport true 25 | textOutput 'stdout' 26 | } 27 | 28 | buildTypes { 29 | release { 30 | minifyEnabled false 31 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 32 | } 33 | } 34 | } 35 | 36 | dependencies { 37 | compile project(':common') 38 | 39 | compile rootProject.ext.firebaseStorage 40 | 41 | testCompile rootProject.ext.assertj 42 | testCompile rootProject.ext.junit 43 | testCompile rootProject.ext.mockito 44 | } 45 | 46 | apply plugin: 'com.github.kt3k.coveralls' 47 | 48 | coveralls { 49 | jacocoReportPath = "${buildDir}/reports/coverageReport/coverageReport.xml" 50 | } 51 | 52 | apply from: rootProject.file('gradle/gradle-mvn-push.gradle') 53 | -------------------------------------------------------------------------------- /firebase-storage/src/main/java/com/github/b3er/rxfirebase/storage/PutFileWithMetadataAndExistingUriOnSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.storage; 2 | 3 | import android.net.Uri; 4 | import com.github.b3er.rxfirebase.common.GmsTaskListeners; 5 | import com.google.firebase.storage.StorageMetadata; 6 | import com.google.firebase.storage.StorageReference; 7 | import com.google.firebase.storage.UploadTask; 8 | import io.reactivex.SingleEmitter; 9 | import io.reactivex.SingleOnSubscribe; 10 | 11 | final class PutFileWithMetadataAndExistingUriOnSubscribe 12 | implements SingleOnSubscribe { 13 | 14 | private final StorageReference mRef; 15 | 16 | private final Uri mUri; 17 | 18 | private final Uri mExistingUploadUri; 19 | 20 | private StorageMetadata mStorageMetadata; 21 | 22 | PutFileWithMetadataAndExistingUriOnSubscribe(StorageReference ref, Uri uri, 23 | StorageMetadata storageMetadata, Uri existingUploadUri) { 24 | mRef = ref; 25 | mUri = uri; 26 | mStorageMetadata = storageMetadata; 27 | mExistingUploadUri = existingUploadUri; 28 | } 29 | 30 | @Override public void subscribe(SingleEmitter e) throws Exception { 31 | mRef.putFile(mUri, mStorageMetadata, mExistingUploadUri) 32 | .addOnCompleteListener(GmsTaskListeners.listener(e)); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /firebase-database/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "com.github.b3er.local.properties" version "1.1" 3 | } 4 | apply plugin: 'com.android.library' 5 | 6 | android { 7 | compileSdkVersion rootProject.ext.compileSdkVersion 8 | buildToolsVersion rootProject.ext.buildToolsVersion 9 | 10 | defaultConfig { 11 | minSdkVersion rootProject.ext.minSdkVersion 12 | } 13 | 14 | compileOptions { 15 | sourceCompatibility JavaVersion.VERSION_1_7 16 | targetCompatibility JavaVersion.VERSION_1_7 17 | } 18 | 19 | dexOptions { 20 | preDexLibraries = !rootProject.ext.ci 21 | } 22 | 23 | lintOptions { 24 | textReport true 25 | textOutput 'stdout' 26 | } 27 | 28 | buildTypes { 29 | release { 30 | minifyEnabled false 31 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 32 | } 33 | } 34 | } 35 | 36 | dependencies { 37 | compile project(':common') 38 | 39 | compile rootProject.ext.firebaseDatabase 40 | compile rootProject.ext.retroOptional 41 | 42 | testCompile rootProject.ext.assertj 43 | testCompile rootProject.ext.junit 44 | testCompile rootProject.ext.mockito 45 | } 46 | 47 | apply plugin: 'com.github.kt3k.coveralls' 48 | 49 | coveralls { 50 | jacocoReportPath = "${buildDir}/reports/coverageReport/coverageReport.xml" 51 | } 52 | 53 | apply from: rootProject.file('gradle/gradle-mvn-push.gradle') 54 | -------------------------------------------------------------------------------- /firebase-auth/src/main/java/com/github/b3er/rxfirebase/auth/UserGetTokenOnSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.auth; 2 | 3 | import android.support.annotation.NonNull; 4 | import com.google.android.gms.tasks.OnCompleteListener; 5 | import com.google.android.gms.tasks.Task; 6 | import com.google.firebase.auth.FirebaseUser; 7 | import com.google.firebase.auth.GetTokenResult; 8 | import io.reactivex.SingleEmitter; 9 | import io.reactivex.SingleOnSubscribe; 10 | 11 | final class UserGetTokenOnSubscribe implements SingleOnSubscribe { 12 | 13 | private final FirebaseUser user; 14 | 15 | private final boolean forceRefresh; 16 | 17 | UserGetTokenOnSubscribe(FirebaseUser user, boolean forceRefresh) { 18 | this.user = user; 19 | this.forceRefresh = forceRefresh; 20 | } 21 | 22 | @Override public void subscribe(final SingleEmitter emitter) { 23 | OnCompleteListener listener = new OnCompleteListener() { 24 | @Override public void onComplete(@NonNull Task task) { 25 | if (!task.isSuccessful()) { 26 | if (!emitter.isDisposed()) { 27 | emitter.onError(task.getException()); 28 | } 29 | return; 30 | } 31 | 32 | if (!emitter.isDisposed()) { 33 | emitter.onSuccess(task.getResult().getToken()); 34 | } 35 | } 36 | }; 37 | 38 | user.getToken(forceRefresh).addOnCompleteListener(listener); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /firebase-auth/src/main/java/com/github/b3er/rxfirebase/auth/BaseAuthOnSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.auth; 2 | 3 | import android.support.annotation.NonNull; 4 | import com.google.android.gms.tasks.OnCompleteListener; 5 | import com.google.android.gms.tasks.Task; 6 | import com.google.firebase.auth.AuthResult; 7 | import com.google.firebase.auth.FirebaseAuth; 8 | import com.google.firebase.auth.FirebaseUser; 9 | import io.reactivex.SingleEmitter; 10 | import io.reactivex.SingleOnSubscribe; 11 | 12 | abstract class BaseAuthOnSubscribe implements SingleOnSubscribe { 13 | 14 | private final FirebaseAuth instance; 15 | 16 | BaseAuthOnSubscribe(FirebaseAuth instance) { 17 | this.instance = instance; 18 | } 19 | 20 | protected abstract Task createAuthTask(FirebaseAuth instance); 21 | 22 | @Override public void subscribe(final SingleEmitter emitter) { 23 | final OnCompleteListener listener = new OnCompleteListener() { 24 | @Override public void onComplete(@NonNull Task task) { 25 | if (!task.isSuccessful()) { 26 | if (!emitter.isDisposed()) { 27 | emitter.onError(task.getException()); 28 | } 29 | return; 30 | } 31 | 32 | if (!emitter.isDisposed()) { 33 | emitter.onSuccess(task.getResult().getUser()); 34 | } 35 | } 36 | }; 37 | createAuthTask(instance).addOnCompleteListener(listener); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /common/src/main/java/com/github/b3er/rxfirebase/common/GmsTaskListeners.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.common; 2 | 3 | import android.support.annotation.NonNull; 4 | import com.google.android.gms.tasks.OnCompleteListener; 5 | import com.google.android.gms.tasks.Task; 6 | import io.reactivex.CompletableEmitter; 7 | import io.reactivex.SingleEmitter; 8 | 9 | public final class GmsTaskListeners { 10 | 11 | private GmsTaskListeners() { 12 | throw new AssertionError("No instances"); 13 | } 14 | 15 | public static OnCompleteListener listener(@NonNull final SingleEmitter emitter) { 16 | return new OnCompleteListener() { 17 | @Override public void onComplete(@NonNull Task task) { 18 | if (!task.isSuccessful()) { 19 | if (!emitter.isDisposed()) { 20 | emitter.onError(task.getException()); 21 | } 22 | return; 23 | } 24 | 25 | if (!emitter.isDisposed()) { 26 | emitter.onSuccess(task.getResult()); 27 | } 28 | } 29 | }; 30 | } 31 | 32 | public static OnCompleteListener listener(@NonNull final CompletableEmitter emitter) { 33 | return new OnCompleteListener() { 34 | @Override public void onComplete(@NonNull Task task) { 35 | if (!task.isSuccessful()) { 36 | if (!emitter.isDisposed()) { 37 | emitter.onError(task.getException()); 38 | } 39 | return; 40 | } 41 | 42 | if (!emitter.isDisposed()) { 43 | emitter.onComplete(); 44 | } 45 | } 46 | }; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /firebase-database/src/main/java/com/github/b3er/rxfirebase/database/DataChangesOnSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.database; 2 | 3 | import com.google.firebase.database.DataSnapshot; 4 | import com.google.firebase.database.DatabaseError; 5 | import com.google.firebase.database.DatabaseReference; 6 | import com.google.firebase.database.ValueEventListener; 7 | import io.reactivex.ObservableEmitter; 8 | import io.reactivex.ObservableOnSubscribe; 9 | import io.reactivex.disposables.Disposables; 10 | import io.reactivex.functions.Action; 11 | 12 | final class DataChangesOnSubscribe implements ObservableOnSubscribe { 13 | 14 | private final DatabaseReference ref; 15 | 16 | DataChangesOnSubscribe(DatabaseReference ref) { 17 | this.ref = ref; 18 | } 19 | 20 | @Override public void subscribe(final ObservableEmitter emitter) { 21 | final ValueEventListener listener = new ValueEventListener() { 22 | @Override public void onDataChange(DataSnapshot dataSnapshot) { 23 | if (!emitter.isDisposed()) { 24 | emitter.onNext(dataSnapshot); 25 | } 26 | } 27 | 28 | @Override public void onCancelled(DatabaseError databaseError) { 29 | if (!emitter.isDisposed()) { 30 | emitter.onError(databaseError.toException()); 31 | } 32 | } 33 | }; 34 | 35 | ref.addValueEventListener(listener); 36 | emitter.setDisposable(Disposables.fromAction(new Action() { 37 | @Override public void run() throws Exception { 38 | ref.removeEventListener(listener); 39 | } 40 | })); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /firebase-auth-kotlin/src/main/kotlin/com/github/b3er/rxfirebase/auth/RxFirebaseUser.kt: -------------------------------------------------------------------------------- 1 | @file:Suppress("NOTHING_TO_INLINE") 2 | 3 | package com.github.b3er.rxfirebase.auth 4 | 5 | import com.google.firebase.auth.AuthCredential 6 | import com.google.firebase.auth.AuthResult 7 | import com.google.firebase.auth.FirebaseUser 8 | import com.google.firebase.auth.UserProfileChangeRequest 9 | import io.reactivex.Completable 10 | import io.reactivex.Single 11 | 12 | inline fun FirebaseUser.rxDelete() 13 | : Completable 14 | = RxFirebaseUser.delete(this) 15 | 16 | inline fun FirebaseUser.rxGetToken(forceRefresh: Boolean) 17 | : Single 18 | = RxFirebaseUser.getToken(this, forceRefresh) 19 | 20 | inline fun FirebaseUser.rxLinkWithCredential(credential: AuthCredential) 21 | : Single 22 | = RxFirebaseUser.linkWithCredential(this, credential) 23 | 24 | inline fun FirebaseUser.rxReauthenticate(credential: AuthCredential) 25 | : Completable 26 | = RxFirebaseUser.reauthenticate(this, credential) 27 | 28 | inline fun FirebaseUser.rxReload() 29 | : Completable 30 | = RxFirebaseUser.reload(this) 31 | 32 | inline fun FirebaseUser.rxSendEmailVerification() 33 | : Completable 34 | = RxFirebaseUser.sendEmailVerification(this) 35 | 36 | inline fun FirebaseUser.rxUnlink(provider: String) 37 | : Single 38 | = RxFirebaseUser.unlink(this, provider) 39 | 40 | inline fun FirebaseUser.rxUpdateEmail(email: String) 41 | : Completable 42 | = RxFirebaseUser.updateEmail(this, email) 43 | 44 | inline fun FirebaseUser.rxUpdatePassword(password: String) 45 | : Completable 46 | = RxFirebaseUser.updatePassword(this, password) 47 | 48 | inline fun FirebaseUser.rxUpdateProfile(request: UserProfileChangeRequest) 49 | : Completable 50 | = RxFirebaseUser.updateProfile(this, request) 51 | 52 | -------------------------------------------------------------------------------- /firebase-database/src/main/java/com/github/b3er/rxfirebase/database/ChildMoveEvent.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.database; 2 | 3 | import android.support.annotation.CheckResult; 4 | import android.support.annotation.NonNull; 5 | import android.support.annotation.Nullable; 6 | import com.google.firebase.database.DataSnapshot; 7 | 8 | public final class ChildMoveEvent extends ChildEvent { 9 | 10 | private final String previousChildName; 11 | 12 | private ChildMoveEvent(DataSnapshot dataSnapshot, String previousChildName) { 13 | super(dataSnapshot); 14 | this.previousChildName = previousChildName; 15 | } 16 | 17 | @CheckResult @NonNull 18 | public static ChildMoveEvent create(DataSnapshot dataSnapshot, String previousChildName) { 19 | return new ChildMoveEvent(dataSnapshot, previousChildName); 20 | } 21 | 22 | @Nullable public String previousChildName() { 23 | return previousChildName; 24 | } 25 | 26 | @Override public boolean equals(Object o) { 27 | if (this == o) { 28 | return true; 29 | } 30 | if (o == null || getClass() != o.getClass()) { 31 | return false; 32 | } 33 | if (!super.equals(o)) { 34 | return false; 35 | } 36 | 37 | ChildMoveEvent that = (ChildMoveEvent) o; 38 | 39 | return previousChildName != null ? previousChildName.equals(that.previousChildName) 40 | : that.previousChildName == null; 41 | } 42 | 43 | @Override public int hashCode() { 44 | int result = dataSnapshot.hashCode(); 45 | result = 31 * result + (previousChildName != null ? previousChildName.hashCode() : 0); 46 | return result; 47 | } 48 | 49 | @Override public String toString() { 50 | return "ChildMoveEvent{" 51 | + "dataSnapshot=" 52 | + dataSnapshot 53 | + ", previousChildName='" 54 | + previousChildName 55 | + '\'' 56 | + '}'; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /firebase-database/src/main/java/com/github/b3er/rxfirebase/database/ChildChangeEvent.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.database; 2 | 3 | import android.support.annotation.CheckResult; 4 | import android.support.annotation.NonNull; 5 | import android.support.annotation.Nullable; 6 | import com.google.firebase.database.DataSnapshot; 7 | 8 | public final class ChildChangeEvent extends ChildEvent { 9 | 10 | private final String previousChildName; 11 | 12 | private ChildChangeEvent(DataSnapshot dataSnapshot, String previousChildName) { 13 | super(dataSnapshot); 14 | this.previousChildName = previousChildName; 15 | } 16 | 17 | @CheckResult @NonNull 18 | public static ChildChangeEvent create(DataSnapshot dataSnapshot, String previousChildName) { 19 | return new ChildChangeEvent(dataSnapshot, previousChildName); 20 | } 21 | 22 | @Nullable public String previousChildName() { 23 | return previousChildName; 24 | } 25 | 26 | @Override public boolean equals(Object o) { 27 | if (this == o) { 28 | return true; 29 | } 30 | if (o == null || getClass() != o.getClass()) { 31 | return false; 32 | } 33 | if (!super.equals(o)) { 34 | return false; 35 | } 36 | 37 | ChildChangeEvent that = (ChildChangeEvent) o; 38 | 39 | return previousChildName != null ? previousChildName.equals(that.previousChildName) 40 | : that.previousChildName == null; 41 | } 42 | 43 | @Override public int hashCode() { 44 | int result = dataSnapshot.hashCode(); 45 | result = 31 * result + (previousChildName != null ? previousChildName.hashCode() : 0); 46 | return result; 47 | } 48 | 49 | @Override public String toString() { 50 | return "ChildChangeEvent{" 51 | + "dataSnapshot=" 52 | + dataSnapshot 53 | + ", previousChildName='" 54 | + previousChildName 55 | + '\'' 56 | + '}'; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /firebase-database/src/main/java/com/github/b3er/rxfirebase/database/ChildAddEvent.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.database; 2 | 3 | import android.support.annotation.CheckResult; 4 | import android.support.annotation.NonNull; 5 | import android.support.annotation.Nullable; 6 | import com.google.firebase.database.DataSnapshot; 7 | 8 | public final class ChildAddEvent extends ChildEvent { 9 | 10 | private final String previousChildName; 11 | 12 | private ChildAddEvent(DataSnapshot dataSnapshot, String previousChildName) { 13 | super(dataSnapshot); 14 | this.previousChildName = previousChildName; 15 | } 16 | 17 | @CheckResult @NonNull 18 | public static ChildAddEvent create(DataSnapshot dataSnapshot, String previousChildName) { 19 | return new ChildAddEvent(dataSnapshot, previousChildName); 20 | } 21 | 22 | @Nullable public String previousChildName() { 23 | return previousChildName; 24 | } 25 | 26 | @Override public boolean equals(Object o) { 27 | if (this == o) { 28 | return true; 29 | } 30 | if (o == null || getClass() != o.getClass()) { 31 | return false; 32 | } 33 | if (!super.equals(o)) { 34 | return false; 35 | } 36 | 37 | ChildAddEvent that = (ChildAddEvent) o; 38 | 39 | return previousChildName != null ? previousChildName.equals(that.previousChildName) 40 | : that.previousChildName == null; 41 | } 42 | 43 | @Override public int hashCode() { 44 | int result = super.hashCode(); 45 | result = 31 * result + dataSnapshot.hashCode(); 46 | result = 31 * result + (previousChildName != null ? previousChildName.hashCode() : 0); 47 | return result; 48 | } 49 | 50 | @Override public String toString() { 51 | return "ChildAddEvent{" 52 | + "dataSnapshot=" 53 | + dataSnapshot 54 | + ", previousChildName='" 55 | + previousChildName 56 | + '\'' 57 | + '}'; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /firebase-auth/src/main/java/com/github/b3er/rxfirebase/auth/FetchProvidersForEmailOnSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.auth; 2 | 3 | import android.support.annotation.NonNull; 4 | import com.google.android.gms.tasks.OnCompleteListener; 5 | import com.google.android.gms.tasks.Task; 6 | import com.google.firebase.auth.FirebaseAuth; 7 | import com.google.firebase.auth.ProviderQueryResult; 8 | import io.reactivex.MaybeEmitter; 9 | import io.reactivex.MaybeOnSubscribe; 10 | import java.util.List; 11 | 12 | final class FetchProvidersForEmailOnSubscribe implements MaybeOnSubscribe> { 13 | 14 | private final FirebaseAuth instance; 15 | 16 | private final String email; 17 | 18 | FetchProvidersForEmailOnSubscribe(FirebaseAuth instance, String email) { 19 | this.instance = instance; 20 | this.email = email; 21 | } 22 | 23 | @Override public void subscribe(final MaybeEmitter> emitter) { 24 | 25 | final OnCompleteListener listener = 26 | new OnCompleteListener() { 27 | @Override public void onComplete(@NonNull Task task) { 28 | if (!task.isSuccessful()) { 29 | if (!emitter.isDisposed()) { 30 | emitter.onError(task.getException()); 31 | } 32 | return; 33 | } 34 | 35 | if (!emitter.isDisposed()) { 36 | ProviderQueryResult result = task.getResult(); 37 | if (result != null) { 38 | List providers = result.getProviders(); 39 | if (providers != null) { 40 | emitter.onSuccess(providers); 41 | return; 42 | } 43 | } 44 | emitter.onComplete(); 45 | } 46 | } 47 | }; 48 | 49 | instance.fetchProvidersForEmail(email).addOnCompleteListener(listener); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /firebase-database/src/main/java/com/github/b3er/rxfirebase/database/RunTransactionOnSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.database; 2 | 3 | import com.google.firebase.database.DataSnapshot; 4 | import com.google.firebase.database.DatabaseError; 5 | import com.google.firebase.database.DatabaseReference; 6 | import com.google.firebase.database.MutableData; 7 | import com.google.firebase.database.Transaction; 8 | import io.reactivex.CompletableEmitter; 9 | import io.reactivex.CompletableOnSubscribe; 10 | import io.reactivex.functions.Function; 11 | 12 | final class RunTransactionOnSubscribe implements CompletableOnSubscribe { 13 | 14 | private final DatabaseReference ref; 15 | 16 | private final boolean fireLocalEvents; 17 | 18 | private Function task; 19 | 20 | RunTransactionOnSubscribe(DatabaseReference ref, boolean fireLocalEvents, 21 | Function task) { 22 | this.ref = ref; 23 | this.fireLocalEvents = fireLocalEvents; 24 | this.task = task; 25 | } 26 | 27 | @Override public void subscribe(final CompletableEmitter emitter) { 28 | final Transaction.Handler handler = new Transaction.Handler() { 29 | @Override public Transaction.Result doTransaction(MutableData mutableData) { 30 | try { 31 | return task.apply(mutableData); 32 | } catch (Exception e) { 33 | //TODO: Is this enough? 34 | throw new RuntimeException(e); 35 | } 36 | } 37 | 38 | @Override public void onComplete(DatabaseError databaseError, boolean committed, 39 | DataSnapshot dataSnapshot) { 40 | if (!emitter.isDisposed()) { 41 | if (null == databaseError) { 42 | emitter.onComplete(); 43 | } else { 44 | emitter.onError(databaseError.toException()); 45 | } 46 | } 47 | } 48 | }; 49 | 50 | ref.runTransaction(handler, fireLocalEvents); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /firebase-database/src/main/java/com/github/b3er/rxfirebase/database/ChildEventsOnSubscribe.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.database; 2 | 3 | import com.google.firebase.database.ChildEventListener; 4 | import com.google.firebase.database.DataSnapshot; 5 | import com.google.firebase.database.DatabaseError; 6 | import com.google.firebase.database.DatabaseReference; 7 | import io.reactivex.ObservableEmitter; 8 | import io.reactivex.ObservableOnSubscribe; 9 | import io.reactivex.disposables.Disposables; 10 | import io.reactivex.functions.Action; 11 | 12 | final class ChildEventsOnSubscribe implements ObservableOnSubscribe { 13 | 14 | private DatabaseReference ref; 15 | 16 | ChildEventsOnSubscribe(DatabaseReference ref) { 17 | this.ref = ref; 18 | } 19 | 20 | @Override public void subscribe(final ObservableEmitter emitter) { 21 | final ChildEventListener listener = new ChildEventListener() { 22 | @Override public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) { 23 | if (!emitter.isDisposed()) { 24 | emitter.onNext(ChildAddEvent.create(dataSnapshot, previousChildName)); 25 | } 26 | } 27 | 28 | @Override public void onChildChanged(DataSnapshot dataSnapshot, String previousChildName) { 29 | if (!emitter.isDisposed()) { 30 | emitter.onNext(ChildChangeEvent.create(dataSnapshot, previousChildName)); 31 | } 32 | } 33 | 34 | @Override public void onChildRemoved(DataSnapshot dataSnapshot) { 35 | if (!emitter.isDisposed()) { 36 | emitter.onNext(ChildRemoveEvent.create(dataSnapshot)); 37 | } 38 | } 39 | 40 | @Override public void onChildMoved(DataSnapshot dataSnapshot, String previousChildName) { 41 | if (!emitter.isDisposed()) { 42 | emitter.onNext(ChildMoveEvent.create(dataSnapshot, previousChildName)); 43 | } 44 | } 45 | 46 | @Override public void onCancelled(DatabaseError databaseError) { 47 | if (!emitter.isDisposed()) { 48 | emitter.onError(databaseError.toException()); 49 | } 50 | } 51 | }; 52 | 53 | ref.addChildEventListener(listener); 54 | emitter.setDisposable(Disposables.fromAction(new Action() { 55 | @Override public void run() throws Exception { 56 | ref.removeEventListener(listener); 57 | } 58 | })); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /firebase-auth-kotlin/src/main/kotlin/com/github/b3er/rxfirebase/auth/RxFirebaseAuth.kt: -------------------------------------------------------------------------------- 1 | @file:Suppress("NOTHING_TO_INLINE") 2 | 3 | package com.github.b3er.rxfirebase.auth 4 | 5 | import com.google.firebase.auth.ActionCodeResult 6 | import com.google.firebase.auth.AuthCredential 7 | import com.google.firebase.auth.FirebaseAuth 8 | import com.google.firebase.auth.FirebaseUser 9 | import io.reactivex.Completable 10 | import io.reactivex.Maybe 11 | import io.reactivex.Observable 12 | import io.reactivex.Single 13 | 14 | inline fun FirebaseAuth.authStateChanges() 15 | : Observable 16 | = RxFirebaseAuth.authStateChanges(this) 17 | 18 | inline fun FirebaseAuth.rxCreateUserWithEmailAndPassword(email: String, password: String) 19 | : Single 20 | = RxFirebaseAuth.createUserWithEmailAndPassword(this, email, password) 21 | 22 | inline fun FirebaseAuth.rxFetchProvidersForEmail(email: String) 23 | : Maybe> 24 | = RxFirebaseAuth.fetchProvidersForEmail(this, email) 25 | 26 | inline fun FirebaseAuth.rxGetCurrentUser() 27 | : Maybe 28 | = RxFirebaseAuth.getCurrentUser(this) 29 | 30 | inline fun FirebaseAuth.rxSendPasswordResetEmail(email: String) 31 | : Completable 32 | = RxFirebaseAuth.sendPasswordResetEmail(this, email) 33 | 34 | inline fun FirebaseAuth.rxSignInAnonymous() 35 | : Single 36 | = RxFirebaseAuth.signInAnonymously(this) 37 | 38 | inline fun FirebaseAuth.rxSignInWithCredential(credential: AuthCredential) 39 | : Single 40 | = RxFirebaseAuth.signInWithCredential(this, credential) 41 | 42 | inline fun FirebaseAuth.rxSignInWithCustomToken(token: String) 43 | : Single 44 | = RxFirebaseAuth.signInWithCustomToken(this, token) 45 | 46 | inline fun FirebaseAuth.rxSignInWithEmailAndPassword(email: String, password: String) 47 | : Single 48 | = RxFirebaseAuth.signInWithEmailAndPassword(this, email, password) 49 | 50 | inline fun FirebaseAuth.rxSignOut() 51 | : Completable 52 | = RxFirebaseAuth.signOut(this) 53 | 54 | inline fun FirebaseAuth.rxApplyActionCode(code: String): Completable 55 | = RxFirebaseAuth.applyActionCode(this, code) 56 | 57 | inline fun FirebaseAuth.rxCheckActionCode(code: String): Single 58 | = RxFirebaseAuth.checkActionCode(this, code) 59 | 60 | inline fun FirebaseAuth.rxConfirmPasswordReset(code: String, newPassword: String): Completable 61 | = RxFirebaseAuth.confirmPasswordReset(this, code, newPassword) 62 | 63 | inline fun FirebaseAuth.rxVerifyPasswordResetCode(code: String): Single 64 | = RxFirebaseAuth.verifyPasswordResetCode(this, code) 65 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /firebase-database-kotlin/src/main/kotlin/com/github/b3er/rxfirebase/database/RxFirebaseDatabase.kt: -------------------------------------------------------------------------------- 1 | @file:Suppress("NOTHING_TO_INLINE") 2 | 3 | package com.github.b3er.rxfirebase.database 4 | 5 | import com.google.firebase.database.DataSnapshot 6 | import com.google.firebase.database.DatabaseReference 7 | import com.google.firebase.database.GenericTypeIndicator 8 | import com.google.firebase.database.MutableData 9 | import com.google.firebase.database.Transaction.Result 10 | import com.memoizrlabs.retrooptional.Optional 11 | import io.reactivex.Completable 12 | import io.reactivex.Observable 13 | import io.reactivex.Single 14 | 15 | inline fun DatabaseReference.childEvents() 16 | : Observable 17 | = RxFirebaseDatabase.childEvents(this) 18 | 19 | inline fun DatabaseReference.data() 20 | : Single 21 | = RxFirebaseDatabase.data(this) 22 | 23 | inline fun DatabaseReference.dataChanges() 24 | : Observable 25 | = RxFirebaseDatabase.dataChanges(this) 26 | 27 | inline fun DatabaseReference.dataChangesOf() 28 | : Observable> 29 | = RxFirebaseDatabase.dataChangesOf(this, T::class.java) 30 | 31 | inline fun DatabaseReference.dataChangesOf(typeIndicator: GenericTypeIndicator) 32 | : Observable> 33 | = RxFirebaseDatabase.dataChangesOf(this, typeIndicator) 34 | 35 | inline fun DatabaseReference.dataOf() 36 | : Single> 37 | = RxFirebaseDatabase.dataOf(this, T::class.java) 38 | 39 | inline fun DatabaseReference.dataOf(typeIndicator: GenericTypeIndicator) 40 | : Single> 41 | = RxFirebaseDatabase.dataOf(this, typeIndicator) 42 | 43 | inline fun DatabaseReference.rxSetPriority(priority: Any) 44 | : Completable 45 | = RxFirebaseDatabase.setPriority(this, priority) 46 | 47 | inline fun DatabaseReference.rxSetValue(value: T) 48 | : Completable 49 | = RxFirebaseDatabase.setValue(this, value) 50 | 51 | inline fun DatabaseReference.rxSetValue(value: T, priority: Any) 52 | : Completable 53 | = RxFirebaseDatabase.setValue(this, value, priority) 54 | 55 | inline fun DatabaseReference.rxChildEvents() 56 | : Observable 57 | = RxFirebaseDatabase.childEvents(this) 58 | 59 | inline fun DatabaseReference.rxRunTransaction(noinline task: (MutableData) -> Result) 60 | : Completable 61 | = RxFirebaseDatabase.runTransaction(this, task) 62 | 63 | inline fun DatabaseReference.rxRunTransaction( 64 | fireLocalEvents: Boolean, noinline task: (MutableData) -> Result) 65 | : Completable 66 | = RxFirebaseDatabase.runTransaction(this, fireLocalEvents, task) 67 | 68 | inline fun DatabaseReference.rxUpdateChildren(update: Map) 69 | : Completable 70 | = RxFirebaseDatabase.updateChildren(this, update) 71 | 72 | inline fun DatabaseReference.rxRemove() 73 | : Completable 74 | = RxFirebaseDatabase.removeValue(this) -------------------------------------------------------------------------------- /firebase-storage-kotlin/src/main/kotlin/com/github/b3er/rxfirebase/storage/RxFirebaseStorage.kt: -------------------------------------------------------------------------------- 1 | @file:Suppress("NOTHING_TO_INLINE") 2 | 3 | package com.github.b3er.rxfirebase.storage 4 | 5 | import android.net.Uri 6 | import com.google.firebase.storage.FileDownloadTask 7 | import com.google.firebase.storage.StorageMetadata 8 | import com.google.firebase.storage.StorageReference 9 | import com.google.firebase.storage.StreamDownloadTask 10 | import com.google.firebase.storage.StreamDownloadTask.StreamProcessor 11 | import com.google.firebase.storage.UploadTask 12 | import io.reactivex.Completable 13 | import io.reactivex.Single 14 | import java.io.File 15 | import java.io.InputStream 16 | 17 | inline fun StorageReference.rxGetBytes(maxDownloadSizeBytes: Long) 18 | : Single 19 | = RxFirebaseStorage.getBytes(this, maxDownloadSizeBytes) 20 | 21 | inline fun StorageReference.rxDelete() 22 | : Completable 23 | = RxFirebaseStorage.delete(this) 24 | 25 | inline fun StorageReference.rxGetFile(uri: Uri) 26 | : Single 27 | = RxFirebaseStorage.getFile(this, uri) 28 | 29 | inline fun StorageReference.rxGetFile(file: File) 30 | : Single 31 | = RxFirebaseStorage.getFile(this, file) 32 | 33 | inline fun StorageReference.rxGetMetadata() 34 | : Single 35 | = RxFirebaseStorage.getMetadata(this) 36 | 37 | inline fun StorageReference.rxGetStream() 38 | : Single 39 | = RxFirebaseStorage.getStream(this) 40 | 41 | inline fun StorageReference.rxGetStream(streamProcessor: StreamProcessor) 42 | : Single 43 | = RxFirebaseStorage.getStream(this, streamProcessor) 44 | 45 | inline fun StorageReference.rxGetDownloadUrl() 46 | : Single 47 | = RxFirebaseStorage.getDownloadUrl(this) 48 | 49 | inline fun StorageReference.rxPutBytes(bytes: ByteArray) 50 | : Single 51 | = RxFirebaseStorage.putBytes(this, bytes) 52 | 53 | inline fun StorageReference.rxPutBytes(bytes: ByteArray, storageMetadata: StorageMetadata) 54 | : Single 55 | = RxFirebaseStorage.putBytes(this, bytes, storageMetadata) 56 | 57 | inline fun StorageReference.rxPutFile(uri: Uri) 58 | : Single 59 | = RxFirebaseStorage.putFile(this, uri) 60 | 61 | inline fun StorageReference.rxPutFile(uri: Uri, storageMetadata: StorageMetadata) 62 | : Single 63 | = RxFirebaseStorage.putFile(this, uri, storageMetadata) 64 | 65 | inline fun StorageReference.rxPutFile(uri: Uri, storageMetadata: StorageMetadata, 66 | existingUploadUri: Uri) 67 | : Single 68 | = RxFirebaseStorage.putFile(this, uri, storageMetadata, existingUploadUri) 69 | 70 | inline fun StorageReference.rxPutStream(inputStream: InputStream) 71 | : Single 72 | = RxFirebaseStorage.putStream(this, inputStream) 73 | 74 | inline fun StorageReference.rxPutStream(inputStream: InputStream, storageMetadata: StorageMetadata) 75 | : Single 76 | = RxFirebaseStorage.putStream(this, inputStream, storageMetadata) 77 | 78 | inline fun StorageReference.rxUpdateMetadata(storageMetadata: StorageMetadata) 79 | : Single 80 | = RxFirebaseStorage.updateMetadata(this, storageMetadata) -------------------------------------------------------------------------------- /firebase-auth/src/main/java/com/github/b3er/rxfirebase/auth/RxFirebaseUser.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.auth; 2 | 3 | import android.support.annotation.CheckResult; 4 | import android.support.annotation.NonNull; 5 | import com.google.firebase.auth.AuthCredential; 6 | import com.google.firebase.auth.AuthResult; 7 | import com.google.firebase.auth.FirebaseUser; 8 | import com.google.firebase.auth.UserProfileChangeRequest; 9 | import io.reactivex.Completable; 10 | import io.reactivex.Single; 11 | 12 | public final class RxFirebaseUser { 13 | private RxFirebaseUser() { 14 | throw new AssertionError("No instances"); 15 | } 16 | 17 | /** 18 | * @see FirebaseUser#delete() 19 | */ 20 | @CheckResult @NonNull public static Completable delete(@NonNull FirebaseUser user) { 21 | return Completable.create(new UserDeleteOnSubscribe(user)); 22 | } 23 | 24 | /** 25 | * @see FirebaseUser#getToken(boolean) 26 | */ 27 | @CheckResult @NonNull public static Single getToken(@NonNull FirebaseUser user, 28 | boolean forceRefresh) { 29 | return Single.create(new UserGetTokenOnSubscribe(user, forceRefresh)); 30 | } 31 | 32 | /** 33 | * @see FirebaseUser#linkWithCredential(AuthCredential) 34 | */ 35 | @CheckResult @NonNull public static Single linkWithCredential( 36 | @NonNull FirebaseUser user, @NonNull AuthCredential credential) { 37 | return Single.create(new UserLinkWithCredentialOnSubscribe(user, credential)); 38 | } 39 | 40 | /** 41 | * @see FirebaseUser#reauthenticate(AuthCredential) 42 | */ 43 | @CheckResult @NonNull public static Completable reauthenticate(@NonNull FirebaseUser user, 44 | @NonNull AuthCredential credential) { 45 | return Completable.create(new UserReauthenticateOnSubscribe(user, credential)); 46 | } 47 | 48 | /** 49 | * @see FirebaseUser#reload() 50 | */ 51 | @CheckResult @NonNull public static Completable reload(@NonNull FirebaseUser user) { 52 | return Completable.create(new UserReloadOnSubscribe(user)); 53 | } 54 | 55 | /** 56 | * @see FirebaseUser#sendEmailVerification() 57 | */ 58 | @CheckResult @NonNull public static Completable sendEmailVerification( 59 | @NonNull FirebaseUser user) { 60 | return Completable.create(new UserSendEmailVerificationOnSubscribe(user)); 61 | } 62 | 63 | /** 64 | * @see FirebaseUser#unlink(String) 65 | */ 66 | @CheckResult @NonNull public static Single unlink(@NonNull FirebaseUser user, 67 | @NonNull String provider) { 68 | return Single.create(new UserUnlinkOnSubscribe(user, provider)); 69 | } 70 | 71 | /** 72 | * @see FirebaseUser#updateEmail(String) 73 | */ 74 | @CheckResult @NonNull public static Completable updateEmail(@NonNull FirebaseUser user, 75 | @NonNull String email) { 76 | return Completable.create(new UserUpdateEmailOnSubscribe(user, email)); 77 | } 78 | 79 | /** 80 | * @see FirebaseUser#updatePassword(String) 81 | */ 82 | @CheckResult @NonNull public static Completable updatePassword(@NonNull FirebaseUser user, 83 | @NonNull String password) { 84 | return Completable.create(new UserUpdatePasswordOnSubscribe(user, password)); 85 | } 86 | 87 | /** 88 | * @see FirebaseUser#updateProfile(UserProfileChangeRequest) 89 | */ 90 | @CheckResult @NonNull public static Completable updateProfile(@NonNull FirebaseUser user, 91 | @NonNull UserProfileChangeRequest request) { 92 | return Completable.create(new UserUpdateProfileOnSubscribe(user, request)); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /gradle/gradle-mvn-push.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 Chris Banes 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | apply plugin: 'maven' 18 | apply plugin: 'signing' 19 | 20 | def isReleaseBuild() { 21 | return VERSION_NAME.contains("SNAPSHOT") == false 22 | } 23 | 24 | def getRepositoryUsername() { 25 | return hasProperty('NEXUS_USERNAME') ? NEXUS_USERNAME : "" 26 | } 27 | 28 | def getRepositoryPassword() { 29 | return hasProperty('NEXUS_PASSWORD') ? NEXUS_PASSWORD : "" 30 | } 31 | 32 | afterEvaluate { project -> 33 | uploadArchives { 34 | repositories { 35 | mavenDeployer { 36 | beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } 37 | 38 | pom.groupId = GROUP 39 | pom.artifactId = POM_ARTIFACT_ID 40 | pom.version = VERSION_NAME 41 | 42 | repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") { 43 | authentication(userName: getRepositoryUsername(), password: getRepositoryPassword()) 44 | } 45 | snapshotRepository(url: "https://oss.sonatype.org/content/repositories/snapshots/") { 46 | authentication(userName: getRepositoryUsername(), password: getRepositoryPassword()) 47 | } 48 | 49 | pom.project { 50 | name POM_NAME 51 | packaging POM_PACKAGING 52 | description POM_DESCRIPTION 53 | url POM_URL 54 | 55 | scm { 56 | url POM_SCM_URL 57 | connection POM_SCM_CONNECTION 58 | developerConnection POM_SCM_DEV_CONNECTION 59 | } 60 | 61 | licenses { 62 | license { 63 | name POM_LICENCE_NAME 64 | url POM_LICENCE_URL 65 | distribution POM_LICENCE_DIST 66 | } 67 | } 68 | 69 | developers { 70 | developer { 71 | id POM_DEVELOPER_ID 72 | name POM_DEVELOPER_NAME 73 | email POM_DEVELOPER_EMAIL 74 | } 75 | } 76 | } 77 | 78 | pom.whenConfigured { pom -> 79 | pom.dependencies.forEach { dep -> 80 | if ("unspecified" == dep.getVersion()) { 81 | dep.setGroupId(GROUP) 82 | dep.setVersion(VERSION_NAME) 83 | } 84 | } 85 | } 86 | } 87 | } 88 | } 89 | 90 | signing { 91 | required { isReleaseBuild() && gradle.taskGraph.hasTask("uploadArchives") } 92 | sign configurations.archives 93 | } 94 | 95 | task androidJavadocs(type: Javadoc) { 96 | if (!project.plugins.hasPlugin('kotlin-android')) { 97 | source = android.sourceSets.main.java.srcDirs 98 | } 99 | classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) 100 | exclude '**/internal/*' 101 | 102 | if (JavaVersion.current().isJava8Compatible()) { 103 | options.addStringOption('Xdoclint:none', '-quiet') 104 | } 105 | } 106 | 107 | task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) { 108 | classifier = 'javadoc' 109 | from androidJavadocs.destinationDir 110 | } 111 | 112 | task androidSourcesJar(type: Jar) { 113 | classifier = 'sources' 114 | from android.sourceSets.main.java.sourceFiles 115 | } 116 | 117 | artifacts { 118 | archives androidSourcesJar 119 | archives androidJavadocsJar 120 | } 121 | } -------------------------------------------------------------------------------- /firebase-database/src/test/java/com/github/b3er/rxfirebase/database/ChildEventTest.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.database; 2 | 3 | import com.google.firebase.database.DataSnapshot; 4 | import org.junit.Before; 5 | import org.junit.Test; 6 | import org.mockito.Mock; 7 | import org.mockito.MockitoAnnotations; 8 | 9 | import static org.assertj.core.api.Assertions.assertThat; 10 | 11 | public class ChildEventTest { 12 | 13 | @Mock DataSnapshot mockDataSnapshot1; 14 | 15 | @Mock DataSnapshot mockDataSnapshot2; 16 | 17 | @Before public void setup() { 18 | MockitoAnnotations.initMocks(this); 19 | } 20 | 21 | @Test public void testChildAddEvent_equals_dataSnapshot() { 22 | ChildAddEvent a = ChildAddEvent.create(mockDataSnapshot1, "foo"); 23 | ChildAddEvent b = ChildAddEvent.create(mockDataSnapshot1, "foo"); 24 | ChildAddEvent c = ChildAddEvent.create(mockDataSnapshot2, "foo"); 25 | 26 | assertThat(a).isEqualTo(a).isNotEqualTo(null).isEqualTo(b).isNotEqualTo(c); 27 | 28 | assertThat(a.hashCode()).isEqualTo(b.hashCode()).isNotEqualTo(c.hashCode()); 29 | } 30 | 31 | @Test public void testChildAddEvent_equals_previousChildName() { 32 | ChildAddEvent a = ChildAddEvent.create(mockDataSnapshot1, "foo"); 33 | ChildAddEvent b = ChildAddEvent.create(mockDataSnapshot1, "foo"); 34 | ChildAddEvent c = ChildAddEvent.create(mockDataSnapshot1, "bar"); 35 | ChildAddEvent d = ChildAddEvent.create(mockDataSnapshot1, null); 36 | 37 | assertThat(a).isEqualTo(a).isNotEqualTo(null).isEqualTo(b).isNotEqualTo(c).isNotEqualTo(d); 38 | 39 | assertThat(a.hashCode()).isEqualTo(b.hashCode()) 40 | .isNotEqualTo(c.hashCode()) 41 | .isNotEqualTo(d.hashCode()); 42 | } 43 | 44 | @Test public void testChildAddEvent_toString() { 45 | ChildAddEvent e = ChildAddEvent.create(mockDataSnapshot1, "foo"); 46 | 47 | assertThat(e.toString()).startsWith("ChildAddEvent"); 48 | } 49 | 50 | @Test public void testChildChangeEvent_equals_dataSnapshot() { 51 | ChildChangeEvent a = ChildChangeEvent.create(mockDataSnapshot1, "foo"); 52 | ChildChangeEvent b = ChildChangeEvent.create(mockDataSnapshot1, "foo"); 53 | ChildChangeEvent c = ChildChangeEvent.create(mockDataSnapshot2, "foo"); 54 | 55 | assertThat(a).isEqualTo(b).isNotEqualTo(c); 56 | 57 | assertThat(a.hashCode()).isEqualTo(b.hashCode()).isNotEqualTo(c.hashCode()); 58 | } 59 | 60 | @Test public void testChildChangeEvent_equals_previousChildName() { 61 | ChildChangeEvent a = ChildChangeEvent.create(mockDataSnapshot1, "foo"); 62 | ChildChangeEvent b = ChildChangeEvent.create(mockDataSnapshot1, "foo"); 63 | ChildChangeEvent c = ChildChangeEvent.create(mockDataSnapshot1, "bar"); 64 | ChildChangeEvent d = ChildChangeEvent.create(mockDataSnapshot1, null); 65 | 66 | assertThat(a).isEqualTo(b).isNotEqualTo(c).isNotEqualTo(d); 67 | 68 | assertThat(a.hashCode()).isEqualTo(b.hashCode()) 69 | .isNotEqualTo(c.hashCode()) 70 | .isNotEqualTo(d.hashCode()); 71 | } 72 | 73 | @Test public void testChildChangeEvent_toString() { 74 | ChildChangeEvent e = ChildChangeEvent.create(mockDataSnapshot1, "foo"); 75 | 76 | assertThat(e.toString()).startsWith("ChildChangeEvent"); 77 | } 78 | 79 | @Test public void testChildMoveEvent_equals_dataSnapshot() { 80 | ChildMoveEvent a = ChildMoveEvent.create(mockDataSnapshot1, "foo"); 81 | ChildMoveEvent b = ChildMoveEvent.create(mockDataSnapshot1, "foo"); 82 | ChildMoveEvent c = ChildMoveEvent.create(mockDataSnapshot2, "foo"); 83 | 84 | assertThat(a).isEqualTo(b).isNotEqualTo(c); 85 | 86 | assertThat(a.hashCode()).isEqualTo(b.hashCode()).isNotEqualTo(c.hashCode()); 87 | } 88 | 89 | @Test public void testChildMoveEvent_equals_previousChildName() { 90 | ChildMoveEvent a = ChildMoveEvent.create(mockDataSnapshot1, "foo"); 91 | ChildMoveEvent b = ChildMoveEvent.create(mockDataSnapshot1, "foo"); 92 | ChildMoveEvent c = ChildMoveEvent.create(mockDataSnapshot1, "bar"); 93 | ChildMoveEvent d = ChildMoveEvent.create(mockDataSnapshot1, null); 94 | 95 | assertThat(a).isEqualTo(b).isNotEqualTo(c).isNotEqualTo(d); 96 | 97 | assertThat(a.hashCode()).isEqualTo(b.hashCode()) 98 | .isNotEqualTo(c.hashCode()) 99 | .isNotEqualTo(d.hashCode()); 100 | } 101 | 102 | @Test public void testChildMoveEvent_toString() { 103 | ChildMoveEvent e = ChildMoveEvent.create(mockDataSnapshot1, "foo"); 104 | 105 | assertThat(e.toString()).startsWith("ChildMoveEvent"); 106 | } 107 | 108 | @Test public void testChildRemoveEvent_equals() { 109 | ChildRemoveEvent a = ChildRemoveEvent.create(mockDataSnapshot1); 110 | ChildRemoveEvent b = ChildRemoveEvent.create(mockDataSnapshot1); 111 | ChildRemoveEvent c = ChildRemoveEvent.create(mockDataSnapshot2); 112 | 113 | assertThat(a).isEqualTo(b).isNotEqualTo(c); 114 | 115 | assertThat(a.hashCode()).isEqualTo(b.hashCode()).isNotEqualTo(c.hashCode()); 116 | } 117 | 118 | @Test public void testChildRemoveEvent_toString() { 119 | ChildRemoveEvent e = ChildRemoveEvent.create(mockDataSnapshot1); 120 | 121 | assertThat(e.toString()).startsWith("ChildRemoveEvent"); 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /firebase-auth/src/main/java/com/github/b3er/rxfirebase/auth/RxFirebaseAuth.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.auth; 2 | 3 | import android.support.annotation.CheckResult; 4 | import android.support.annotation.NonNull; 5 | import com.google.firebase.auth.ActionCodeResult; 6 | import com.google.firebase.auth.AuthCredential; 7 | import com.google.firebase.auth.FirebaseAuth; 8 | import com.google.firebase.auth.FirebaseUser; 9 | import io.reactivex.Completable; 10 | import io.reactivex.Maybe; 11 | import io.reactivex.Observable; 12 | import io.reactivex.Single; 13 | import java.util.List; 14 | 15 | public final class RxFirebaseAuth { 16 | private RxFirebaseAuth() { 17 | throw new AssertionError("No instances"); 18 | } 19 | 20 | /** 21 | * @see FirebaseAuth#addAuthStateListener(FirebaseAuth.AuthStateListener) 22 | */ 23 | @CheckResult @NonNull public static Observable authStateChanges( 24 | @NonNull FirebaseAuth instance) { 25 | return Observable.create(new AuthStateChangesOnSubscribe(instance)); 26 | } 27 | 28 | /** 29 | * @see FirebaseAuth#createUserWithEmailAndPassword(String, String) 30 | */ 31 | @CheckResult @NonNull public static Single createUserWithEmailAndPassword( 32 | @NonNull FirebaseAuth instance, @NonNull String email, @NonNull String password) { 33 | return Single.create(new CreateUserWithEmailAndPasswordOnSubscribe(instance, email, password)); 34 | } 35 | 36 | /** 37 | * @see FirebaseAuth#fetchProvidersForEmail(String) 38 | */ 39 | @CheckResult @NonNull public static Maybe> fetchProvidersForEmail( 40 | @NonNull FirebaseAuth instance, @NonNull String email) { 41 | return Maybe.create(new FetchProvidersForEmailOnSubscribe(instance, email)); 42 | } 43 | 44 | /** 45 | * @see FirebaseAuth#getCurrentUser() 46 | */ 47 | @CheckResult @NonNull public static Maybe getCurrentUser( 48 | @NonNull final FirebaseAuth instance) { 49 | return Maybe.create(new GetCurrentUserOnSubscribe(instance)); 50 | } 51 | 52 | /** 53 | * @see FirebaseAuth#sendPasswordResetEmail(String) 54 | */ 55 | @CheckResult @NonNull public static Completable sendPasswordResetEmail( 56 | @NonNull FirebaseAuth instance, @NonNull String email) { 57 | return Completable.create(new SendPasswordResetEmailOnSubscribe(instance, email)); 58 | } 59 | 60 | /** 61 | * @see FirebaseAuth#signInAnonymously() 62 | */ 63 | @CheckResult @NonNull public static Single signInAnonymously( 64 | @NonNull FirebaseAuth instance) { 65 | return Single.create(new SignInAnonymouslyOnSubscribe(instance)); 66 | } 67 | 68 | /** 69 | * @see FirebaseAuth#signInWithCredential(AuthCredential) 70 | */ 71 | @CheckResult @NonNull public static Single signInWithCredential( 72 | @NonNull FirebaseAuth instance, @NonNull AuthCredential credential) { 73 | return Single.create(new SignInWithCredentialOnSubscribe(instance, credential)); 74 | } 75 | 76 | /** 77 | * @see FirebaseAuth#signInWithCustomToken(String) 78 | */ 79 | @CheckResult @NonNull public static Single signInWithCustomToken( 80 | @NonNull FirebaseAuth instance, @NonNull String token) { 81 | return Single.create(new SignInWithCustomTokenOnSubscribe(instance, token)); 82 | } 83 | 84 | /** 85 | * @see FirebaseAuth#signInWithEmailAndPassword(String, String) 86 | */ 87 | @CheckResult @NonNull public static Single signInWithEmailAndPassword( 88 | @NonNull FirebaseAuth instance, @NonNull String email, @NonNull String password) { 89 | return Single.create(new SignInWithEmailAndPasswordOnSubscribe(instance, email, password)); 90 | } 91 | 92 | /** 93 | * @see FirebaseAuth#signOut() 94 | */ 95 | @CheckResult @NonNull public static Completable signOut(@NonNull FirebaseAuth instance) { 96 | return Completable.create(new SignOutOnSubscribe(instance)); 97 | } 98 | 99 | /** 100 | * @see FirebaseAuth#applyActionCode(String) 101 | */ 102 | @CheckResult @NonNull public static Completable applyActionCode(@NonNull FirebaseAuth instance, 103 | @NonNull String code) { 104 | return Completable.create(new ApplyActionCodeOnSubscribe(instance, code)); 105 | } 106 | 107 | /** 108 | * @see FirebaseAuth#checkActionCode(String) 109 | */ 110 | @CheckResult @NonNull public static Single checkActionCode( 111 | @NonNull FirebaseAuth instance, @NonNull String code) { 112 | return Single.create(new CheckActionCodeOnSubscribe(instance, code)); 113 | } 114 | 115 | /** 116 | * @see FirebaseAuth#confirmPasswordReset(String, String) 117 | */ 118 | @CheckResult @NonNull public static Completable confirmPasswordReset( 119 | @NonNull FirebaseAuth instance, @NonNull String code, @NonNull String newPassword) { 120 | return Completable.create(new ConfirmPasswordResetOnSubscribe(instance, code, newPassword)); 121 | } 122 | 123 | /** 124 | * @see FirebaseAuth#verifyPasswordResetCode(String) 125 | */ 126 | @CheckResult @NonNull public static Single verifyPasswordResetCode( 127 | @NonNull FirebaseAuth instance, @NonNull String code) { 128 | return Single.create(new VerifyPasswordResetCodeOnSubscribe(instance, code)); 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /firebase-storage/src/main/java/com/github/b3er/rxfirebase/storage/RxFirebaseStorage.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.storage; 2 | 3 | import android.net.Uri; 4 | import android.support.annotation.NonNull; 5 | import android.support.annotation.Nullable; 6 | import com.google.firebase.storage.FileDownloadTask; 7 | import com.google.firebase.storage.StorageMetadata; 8 | import com.google.firebase.storage.StorageReference; 9 | import com.google.firebase.storage.StreamDownloadTask; 10 | import com.google.firebase.storage.UploadTask; 11 | import io.reactivex.Completable; 12 | import io.reactivex.Observable; 13 | import io.reactivex.Single; 14 | import java.io.File; 15 | import java.io.InputStream; 16 | 17 | public final class RxFirebaseStorage { 18 | 19 | private RxFirebaseStorage() { 20 | throw new AssertionError("No instances"); 21 | } 22 | 23 | /** 24 | * @see StorageReference#getBytes(long) 25 | */ 26 | public static Single getBytes(@NonNull StorageReference ref, 27 | final long maxDownloadSizeBytes) { 28 | return Single.create(new GetBytesOnSubscribe(ref, maxDownloadSizeBytes)); 29 | } 30 | 31 | /** 32 | * @see StorageReference#delete() 33 | */ 34 | public static Completable delete(@NonNull StorageReference ref) { 35 | return Completable.create(new DeleteOnSubscribe(ref)); 36 | } 37 | 38 | /** 39 | * @see StorageReference#getFile(Uri) 40 | */ 41 | public static Single getFile(@NonNull StorageReference ref, 42 | @NonNull Uri uri) { 43 | return Single.create(new GetFileToUriOnSubscribe(ref, uri)); 44 | } 45 | 46 | /** 47 | * @see StorageReference#getFile(File) 48 | */ 49 | public static Single getFile(@NonNull StorageReference ref, 50 | @NonNull File file) { 51 | return Single.create(new GetFileToFileOnSubscribe(ref, file)); 52 | } 53 | 54 | /** 55 | * @see StorageReference#getMetadata() 56 | */ 57 | public static Single getMetadata(@NonNull StorageReference ref) { 58 | return Single.create(new GetMetadataOnSubscribe(ref)); 59 | } 60 | 61 | /** 62 | * @see StorageReference#getStream() 63 | */ 64 | public static Single getStream(@NonNull StorageReference ref) { 65 | return Single.create(new GetStreamOnSubscribe(ref)); 66 | } 67 | 68 | /** 69 | * @see StorageReference#getStream(StreamDownloadTask.StreamProcessor) 70 | */ 71 | public static Single getStream(@NonNull StorageReference ref, 72 | StreamDownloadTask.StreamProcessor streamProcessor) { 73 | return Single.create(new GetStreamWithProcessorOnSubscribe(ref, streamProcessor)); 74 | } 75 | 76 | /** 77 | * @see StorageReference#getDownloadUrl() 78 | */ 79 | public static Single getDownloadUrl(@NonNull StorageReference ref) { 80 | return Single.create(new GetDownloadUriOnSubscribe(ref)); 81 | } 82 | 83 | /** 84 | * @see StorageReference#putBytes(byte[]) 85 | */ 86 | public static Single putBytes(@NonNull StorageReference ref, 87 | byte[] bytes) { 88 | return Single.create(new PutBytesOnSubscribe(ref, bytes)); 89 | } 90 | 91 | /** 92 | * @see StorageReference#putBytes(byte[], StorageMetadata) 93 | */ 94 | public static Single putBytes(@NonNull StorageReference ref, 95 | byte[] bytes, StorageMetadata storageMetadata) { 96 | return Single.create(new PutBytesWithMetadataOnSubscribe(ref, bytes, storageMetadata)); 97 | } 98 | 99 | /** 100 | * @see StorageReference#putFile(Uri) 101 | */ 102 | public static Single putFile(@NonNull StorageReference ref, 103 | @NonNull Uri uri) { 104 | return Single.create(new PutFileOnSubscribe(ref, uri)); 105 | } 106 | 107 | /** 108 | * @see StorageReference#putFile(Uri, StorageMetadata) 109 | */ 110 | public static Single putFile(@NonNull StorageReference ref, 111 | @NonNull Uri uri, @NonNull StorageMetadata storageMetadata) { 112 | return Single.create(new PutFileWithMetadataOnSubscribe(ref, uri, storageMetadata)); 113 | } 114 | 115 | /** 116 | * @see StorageReference#putFile(Uri, StorageMetadata, Uri) 117 | */ 118 | public static Single putFile(@NonNull StorageReference ref, 119 | @NonNull Uri uri, @Nullable StorageMetadata storageMetadata, 120 | @Nullable Uri existingUploadUri) { 121 | return Single.create(new PutFileWithMetadataAndExistingUriOnSubscribe(ref, uri, storageMetadata, 122 | existingUploadUri)); 123 | } 124 | 125 | /** 126 | * @see StorageReference#putStream(InputStream) 127 | */ 128 | public static Single putStream(@NonNull StorageReference ref, 129 | @NonNull InputStream inputStream) { 130 | return Single.create(new PutStreamOnSubscribe(ref, inputStream)); 131 | } 132 | 133 | /** 134 | * @see StorageReference#putStream(InputStream, StorageMetadata) 135 | */ 136 | public static Single putStream(@NonNull StorageReference ref, 137 | @NonNull InputStream inputStream, @NonNull StorageMetadata storageMetadata) { 138 | return Single.create(new PutStreamWithMetadataOnSubscribe(ref, inputStream, storageMetadata)); 139 | } 140 | 141 | /** 142 | * @see StorageReference#updateMetadata(StorageMetadata) 143 | */ 144 | public static Single updateMetadata(@NonNull StorageReference ref, 145 | @NonNull StorageMetadata storageMetadata) { 146 | return Single.create(new UpdateMetadataOnSubscribe(ref, storageMetadata)); 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn ( ) { 37 | echo "$*" 38 | } 39 | 40 | die ( ) { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /firebase-database/src/main/java/com/github/b3er/rxfirebase/database/RxFirebaseDatabase.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.database; 2 | 3 | import android.support.annotation.CheckResult; 4 | import android.support.annotation.NonNull; 5 | import android.support.annotation.Nullable; 6 | import com.github.b3er.rxfirebase.database.transformers.ObsTransformerOfClazz; 7 | import com.github.b3er.rxfirebase.database.transformers.ObsTransformerOfGenericTypeIndicator; 8 | import com.github.b3er.rxfirebase.database.transformers.SingleTransformerOfClazz; 9 | import com.github.b3er.rxfirebase.database.transformers.SingleTransformerOfGenericTypeIndicator; 10 | import com.google.firebase.database.DataSnapshot; 11 | import com.google.firebase.database.DatabaseReference; 12 | import com.google.firebase.database.GenericTypeIndicator; 13 | import com.google.firebase.database.MutableData; 14 | import com.google.firebase.database.Transaction; 15 | import com.memoizrlabs.retrooptional.Optional; 16 | import io.reactivex.Completable; 17 | import io.reactivex.Observable; 18 | import io.reactivex.Single; 19 | import io.reactivex.functions.Function; 20 | import java.util.Map; 21 | 22 | public final class RxFirebaseDatabase { 23 | private RxFirebaseDatabase() { 24 | throw new AssertionError("No instances"); 25 | } 26 | 27 | /** 28 | * @see DatabaseReference#addChildEventListener(ChildEventListener) 29 | */ 30 | @NonNull @CheckResult public static Observable childEvents( 31 | @NonNull DatabaseReference ref) { 32 | return Observable.create(new ChildEventsOnSubscribe(ref)); 33 | } 34 | 35 | /** 36 | * @see DatabaseReference#addListenerForSingleValueEvent(ValueEventListener) 37 | */ 38 | @NonNull @CheckResult public static Single data(@NonNull DatabaseReference ref) { 39 | return Single.create(new DataOnSubscribe(ref)); 40 | } 41 | 42 | /** 43 | * @see DatabaseReference#addValueEventListener(ValueEventListener) 44 | */ 45 | @NonNull @CheckResult public static Observable dataChanges( 46 | @NonNull DatabaseReference ref) { 47 | return Observable.create(new DataChangesOnSubscribe(ref)); 48 | } 49 | 50 | /** 51 | * @see DatabaseReference#addValueEventListener(ValueEventListener) 52 | */ 53 | @NonNull @CheckResult public static Observable> dataChangesOf( 54 | @NonNull DatabaseReference ref, @NonNull Class clazz) { 55 | return dataChanges(ref).compose(new ObsTransformerOfClazz<>(clazz)); 56 | } 57 | 58 | /** 59 | * @see DatabaseReference#addValueEventListener(ValueEventListener) 60 | */ 61 | @NonNull @CheckResult public static Observable> dataChangesOf( 62 | @NonNull DatabaseReference ref, @NonNull GenericTypeIndicator typeIndicator) { 63 | return dataChanges(ref).compose(new ObsTransformerOfGenericTypeIndicator(typeIndicator)); 64 | } 65 | 66 | /** 67 | * @see DatabaseReference#addListenerForSingleValueEvent(ValueEventListener) 68 | */ 69 | @NonNull @CheckResult public static Single> dataOf(@NonNull DatabaseReference ref, 70 | @NonNull Class clazz) { 71 | return data(ref).compose(new SingleTransformerOfClazz<>(clazz)); 72 | } 73 | 74 | /** 75 | * @see DatabaseReference#addListenerForSingleValueEvent(ValueEventListener) 76 | */ 77 | @NonNull @CheckResult public static Single> dataOf(@NonNull DatabaseReference ref, 78 | @NonNull GenericTypeIndicator typeIndicator) { 79 | return data(ref).compose(new SingleTransformerOfGenericTypeIndicator(typeIndicator)); 80 | } 81 | 82 | /** 83 | * @see DatabaseReference#removeValue() 84 | */ 85 | @NonNull @CheckResult public static Completable removeValue(@NonNull DatabaseReference ref) { 86 | return Completable.create(new RemoveValueOnSubscribe(ref)); 87 | } 88 | 89 | /** 90 | * @see DatabaseReference#setPriority(Object) 91 | */ 92 | @NonNull @CheckResult public static Completable setPriority(@NonNull DatabaseReference ref, 93 | @NonNull Object priority) { 94 | return Completable.create(new SetPriorityOnSubscribe(ref, priority)); 95 | } 96 | 97 | /** 98 | * @see DatabaseReference#setValue(Object) 99 | */ 100 | @NonNull @CheckResult public static Completable setValue(@NonNull DatabaseReference ref, 101 | @Nullable T value) { 102 | return Completable.create(new SetValueOnSubscribe(ref, value)); 103 | } 104 | 105 | /** 106 | * @see DatabaseReference#setValue(Object, Object) 107 | */ 108 | @NonNull @CheckResult public static Completable setValue(@NonNull DatabaseReference ref, 109 | @Nullable T value, @NonNull Object priority) { 110 | return Completable.create(new SetValueWithPriorityOnSubscribe(ref, value, priority)); 111 | } 112 | 113 | /** 114 | * @see DatabaseReference#runTransaction(Transaction.Handler) 115 | */ 116 | @NonNull @CheckResult public static Completable runTransaction(@NonNull DatabaseReference ref, 117 | @NonNull Function task) { 118 | return runTransaction(ref, true, task); 119 | } 120 | 121 | /** 122 | * @see DatabaseReference#runTransaction(Transaction.Handler, boolean) 123 | */ 124 | @NonNull @CheckResult public static Completable runTransaction(@NonNull DatabaseReference ref, 125 | boolean fireLocalEvents, @NonNull Function task) { 126 | return Completable.create(new RunTransactionOnSubscribe(ref, fireLocalEvents, task)); 127 | } 128 | 129 | /** 130 | * @see DatabaseReference#updateChildren(Map) 131 | */ 132 | @NonNull @CheckResult public static Completable updateChildren(@NonNull DatabaseReference ref, 133 | @NonNull Map update) { 134 | return Completable.create(new UpdateChildrenOnSubscribe(ref, update)); 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /config/checkstyle/checkstyle.xsl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 81 | 84 | 85 | 86 | 90 | 91 |
77 | 80 | 82 |

CheckStyle Audit

83 |
Designed for use with CheckStyle 88 | and Ant. 89 |
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 |

Files

119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 134 | 137 | 138 | 139 |
NameErrors
130 | 131 | 132 | 133 | 135 | 136 |
140 |
141 | 142 | 143 | 144 | 145 |

File 146 | 147 |

148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 160 | 163 | 164 | 165 |
Error DescriptionLine
158 | 159 | 161 | 162 |
166 | Back to top 167 |
168 | 169 | 170 | 171 |

Summary

172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 184 | 187 | 188 |
FilesErrors
182 | 183 | 185 | 186 |
189 |
190 | 191 | 192 | 193 | a 194 | b 195 | 196 | 197 |
198 | -------------------------------------------------------------------------------- /config/checkstyle/checkstyle.xml: -------------------------------------------------------------------------------- 1 | 2 | 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 | 54 | 55 | 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 | 90 | 91 | 92 | 93 | 94 | 96 | 97 | 98 | 99 | 100 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 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 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /firebase-auth/src/test/java/com/github/b3er/rxfirebase/auth/RxFirebaseUserTest.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.auth; 2 | 3 | import com.google.android.gms.tasks.OnCompleteListener; 4 | import com.google.android.gms.tasks.Task; 5 | import com.google.firebase.auth.AuthCredential; 6 | import com.google.firebase.auth.AuthResult; 7 | import com.google.firebase.auth.FirebaseUser; 8 | import com.google.firebase.auth.GetTokenResult; 9 | import com.google.firebase.auth.UserProfileChangeRequest; 10 | import io.reactivex.observers.TestObserver; 11 | import org.junit.Before; 12 | import org.junit.Test; 13 | import org.mockito.ArgumentCaptor; 14 | import org.mockito.Mock; 15 | import org.mockito.MockitoAnnotations; 16 | 17 | import static org.mockito.Mockito.verify; 18 | import static org.mockito.Mockito.when; 19 | 20 | public class RxFirebaseUserTest { 21 | 22 | @Mock FirebaseUser mockFirebaseUser; 23 | 24 | @Mock GetTokenResult mockGetTokenResult; 25 | 26 | @Mock AuthCredential mockAuthCredential; 27 | 28 | @Mock AuthResult mockAuthResult; 29 | 30 | @Mock UserProfileChangeRequest mockProfileChangeRequest; 31 | 32 | @Mock Task mockVoidTaskResult; 33 | 34 | @Mock Task mockGetTokenTaskResult; 35 | 36 | @Mock Task mockAuthTaskResult; 37 | 38 | private ArgumentCaptor onComplete; 39 | 40 | @Before public void setUp() { 41 | MockitoAnnotations.initMocks(this); 42 | 43 | onComplete = ArgumentCaptor.forClass(OnCompleteListener.class); 44 | } 45 | 46 | @Test public void testDelete() { 47 | mockVoidResult(true); 48 | when(mockFirebaseUser.delete()).thenReturn(mockVoidTaskResult); 49 | 50 | TestObserver obs = TestObserver.create(); 51 | 52 | RxFirebaseUser.delete(mockFirebaseUser).subscribe(obs); 53 | 54 | callOnComplete(mockVoidTaskResult); 55 | obs.dispose(); 56 | 57 | // Ensure no more values are emitted after unsubscribe 58 | callOnComplete(mockVoidTaskResult); 59 | 60 | obs.assertNoErrors(); 61 | obs.assertComplete(); 62 | } 63 | 64 | @Test public void testDelete_notSuccessful() { 65 | mockNotSuccessfulVoidResult(new IllegalStateException()); 66 | when(mockFirebaseUser.delete()).thenReturn(mockVoidTaskResult); 67 | 68 | TestObserver obs = TestObserver.create(); 69 | 70 | RxFirebaseUser.delete(mockFirebaseUser).subscribe(obs); 71 | 72 | callOnComplete(mockVoidTaskResult); 73 | obs.dispose(); 74 | 75 | // Ensure no more values are emitted after unsubscribe 76 | callOnComplete(mockVoidTaskResult); 77 | 78 | obs.assertError(IllegalStateException.class); 79 | obs.assertNotComplete(); 80 | } 81 | 82 | @Test public void testGetToken() { 83 | mockSuccessfulTokenResult("token"); 84 | when(mockFirebaseUser.getToken(true)).thenReturn(mockGetTokenTaskResult); 85 | 86 | TestObserver obs = TestObserver.create(); 87 | 88 | RxFirebaseUser.getToken(mockFirebaseUser, true).subscribe(obs); 89 | 90 | callOnComplete(mockGetTokenTaskResult); 91 | obs.dispose(); 92 | 93 | // Ensure no more values are emitted after unsubscribe 94 | callOnComplete(mockGetTokenTaskResult); 95 | 96 | obs.assertNoErrors(); 97 | obs.assertComplete(); 98 | obs.assertValue("token"); 99 | } 100 | 101 | @Test public void testGetToken_notSuccessful() { 102 | mockNotSuccessfulTokenResult(new IllegalStateException()); 103 | when(mockFirebaseUser.getToken(true)).thenReturn(mockGetTokenTaskResult); 104 | 105 | TestObserver obs = TestObserver.create(); 106 | 107 | RxFirebaseUser.getToken(mockFirebaseUser, true).subscribe(obs); 108 | 109 | callOnComplete(mockGetTokenTaskResult); 110 | obs.dispose(); 111 | 112 | // Ensure no more values are emitted after unsubscribe 113 | callOnComplete(mockGetTokenTaskResult); 114 | 115 | obs.assertError(IllegalStateException.class); 116 | obs.assertNoValues(); 117 | } 118 | 119 | @Test public void testLinkWithCredential() { 120 | mockSuccessfulAuthResult(); 121 | when(mockFirebaseUser.linkWithCredential(mockAuthCredential)).thenReturn(mockAuthTaskResult); 122 | 123 | TestObserver obs = TestObserver.create(); 124 | 125 | RxFirebaseUser.linkWithCredential(mockFirebaseUser, mockAuthCredential).subscribe(obs); 126 | 127 | callOnComplete(mockAuthTaskResult); 128 | obs.dispose(); 129 | 130 | // Ensure no more values are emitted after unsubscribe 131 | callOnComplete(mockAuthTaskResult); 132 | 133 | obs.assertNoErrors(); 134 | obs.assertComplete(); 135 | obs.assertValueCount(1); 136 | } 137 | 138 | @Test public void testLinkWithCredential_notSuccessful() { 139 | mockNotSuccessfulAuthResult(new IllegalStateException()); 140 | when(mockFirebaseUser.linkWithCredential(mockAuthCredential)).thenReturn(mockAuthTaskResult); 141 | 142 | TestObserver obs = TestObserver.create(); 143 | 144 | RxFirebaseUser.linkWithCredential(mockFirebaseUser, mockAuthCredential).subscribe(obs); 145 | 146 | callOnComplete(mockAuthTaskResult); 147 | obs.dispose(); 148 | 149 | // Ensure no more values are emitted after unsubscribe 150 | callOnComplete(mockAuthTaskResult); 151 | 152 | obs.assertError(IllegalStateException.class); 153 | obs.assertNoValues(); 154 | } 155 | 156 | @Test public void testReauthenticate() { 157 | mockVoidResult(true); 158 | when(mockFirebaseUser.reauthenticate(mockAuthCredential)).thenReturn(mockVoidTaskResult); 159 | 160 | TestObserver obs = TestObserver.create(); 161 | 162 | RxFirebaseUser.reauthenticate(mockFirebaseUser, mockAuthCredential).subscribe(obs); 163 | 164 | callOnComplete(mockVoidTaskResult); 165 | obs.dispose(); 166 | 167 | // Ensure no more values are emitted after unsubscribe 168 | callOnComplete(mockVoidTaskResult); 169 | 170 | obs.assertNoErrors(); 171 | obs.assertComplete(); 172 | } 173 | 174 | @Test public void testReauthenticate_notSuccessful() { 175 | mockNotSuccessfulVoidResult(new IllegalStateException()); 176 | when(mockFirebaseUser.reauthenticate(mockAuthCredential)).thenReturn(mockVoidTaskResult); 177 | 178 | TestObserver obs = TestObserver.create(); 179 | 180 | RxFirebaseUser.reauthenticate(mockFirebaseUser, mockAuthCredential).subscribe(obs); 181 | 182 | callOnComplete(mockVoidTaskResult); 183 | obs.dispose(); 184 | 185 | // Ensure no more values are emitted after unsubscribe 186 | callOnComplete(mockVoidTaskResult); 187 | 188 | obs.assertError(IllegalStateException.class); 189 | obs.assertNotComplete(); 190 | } 191 | 192 | @Test public void testReload() { 193 | mockVoidResult(true); 194 | when(mockFirebaseUser.reload()).thenReturn(mockVoidTaskResult); 195 | 196 | TestObserver obs = TestObserver.create(); 197 | 198 | RxFirebaseUser.reload(mockFirebaseUser).subscribe(obs); 199 | 200 | callOnComplete(mockVoidTaskResult); 201 | obs.dispose(); 202 | 203 | // Ensure no more values are emitted after unsubscribe 204 | callOnComplete(mockVoidTaskResult); 205 | 206 | obs.assertNoErrors(); 207 | obs.assertComplete(); 208 | } 209 | 210 | @Test public void testReload_notSuccessful() { 211 | mockNotSuccessfulVoidResult(new IllegalStateException()); 212 | when(mockFirebaseUser.reload()).thenReturn(mockVoidTaskResult); 213 | 214 | TestObserver obs = TestObserver.create(); 215 | 216 | RxFirebaseUser.reload(mockFirebaseUser).subscribe(obs); 217 | 218 | callOnComplete(mockVoidTaskResult); 219 | obs.dispose(); 220 | 221 | // Ensure no more values are emitted after unsubscribe 222 | callOnComplete(mockVoidTaskResult); 223 | 224 | obs.assertError(IllegalStateException.class); 225 | obs.assertNotComplete(); 226 | } 227 | 228 | @Test public void testSendEmailVerification() { 229 | mockVoidResult(true); 230 | when(mockFirebaseUser.sendEmailVerification()).thenReturn(mockVoidTaskResult); 231 | 232 | TestObserver obs = TestObserver.create(); 233 | 234 | RxFirebaseUser.sendEmailVerification(mockFirebaseUser).subscribe(obs); 235 | 236 | callOnComplete(mockVoidTaskResult); 237 | obs.dispose(); 238 | 239 | // Ensure no more values are emitted after unsubscribe 240 | callOnComplete(mockVoidTaskResult); 241 | 242 | obs.assertNoErrors(); 243 | obs.assertComplete(); 244 | } 245 | 246 | @Test public void testSendEmailVerification_notSuccessful() { 247 | mockNotSuccessfulVoidResult(new IllegalStateException()); 248 | when(mockFirebaseUser.sendEmailVerification()).thenReturn(mockVoidTaskResult); 249 | 250 | TestObserver obs = TestObserver.create(); 251 | 252 | RxFirebaseUser.sendEmailVerification(mockFirebaseUser).subscribe(obs); 253 | 254 | callOnComplete(mockVoidTaskResult); 255 | obs.dispose(); 256 | 257 | // Ensure no more values are emitted after unsubscribe 258 | callOnComplete(mockVoidTaskResult); 259 | 260 | obs.assertError(IllegalStateException.class); 261 | obs.assertNotComplete(); 262 | } 263 | 264 | @Test public void testUnlink() { 265 | mockSuccessfulAuthResult(); 266 | when(mockFirebaseUser.unlink("provider")).thenReturn(mockAuthTaskResult); 267 | 268 | TestObserver obs = TestObserver.create(); 269 | 270 | RxFirebaseUser.unlink(mockFirebaseUser, "provider").subscribe(obs); 271 | 272 | callOnComplete(mockAuthTaskResult); 273 | obs.dispose(); 274 | 275 | // Ensure no more values are emitted after unsubscribe 276 | callOnComplete(mockAuthTaskResult); 277 | 278 | obs.assertNoErrors(); 279 | obs.assertComplete(); 280 | obs.assertValueCount(1); 281 | } 282 | 283 | @Test public void testUnlink_notSuccessful() { 284 | mockNotSuccessfulAuthResult(new IllegalStateException()); 285 | when(mockFirebaseUser.unlink("provider")).thenReturn(mockAuthTaskResult); 286 | 287 | TestObserver obs = TestObserver.create(); 288 | 289 | RxFirebaseUser.unlink(mockFirebaseUser, "provider").subscribe(obs); 290 | 291 | callOnComplete(mockAuthTaskResult); 292 | obs.dispose(); 293 | 294 | // Ensure no more values are emitted after unsubscribe 295 | callOnComplete(mockAuthTaskResult); 296 | 297 | obs.assertError(IllegalStateException.class); 298 | obs.assertNoValues(); 299 | } 300 | 301 | @Test public void testUpdateEmail() { 302 | mockVoidResult(true); 303 | when(mockFirebaseUser.updateEmail("foo@bar.com")).thenReturn(mockVoidTaskResult); 304 | 305 | TestObserver obs = TestObserver.create(); 306 | 307 | RxFirebaseUser.updateEmail(mockFirebaseUser, "foo@bar.com").subscribe(obs); 308 | 309 | callOnComplete(mockVoidTaskResult); 310 | obs.dispose(); 311 | 312 | // Ensure no more values are emitted after unsubscribe 313 | callOnComplete(mockVoidTaskResult); 314 | 315 | obs.assertNoErrors(); 316 | obs.assertComplete(); 317 | } 318 | 319 | @Test public void testUpdateEmail_notSuccessful() { 320 | mockNotSuccessfulVoidResult(new IllegalStateException()); 321 | when(mockFirebaseUser.updateEmail("foo@bar.com")).thenReturn(mockVoidTaskResult); 322 | 323 | TestObserver obs = TestObserver.create(); 324 | 325 | RxFirebaseUser.updateEmail(mockFirebaseUser, "foo@bar.com").subscribe(obs); 326 | 327 | callOnComplete(mockVoidTaskResult); 328 | obs.dispose(); 329 | 330 | // Ensure no more values are emitted after unsubscribe 331 | callOnComplete(mockVoidTaskResult); 332 | 333 | obs.assertError(IllegalStateException.class); 334 | obs.assertNotComplete(); 335 | } 336 | 337 | @Test public void testUpdatePassword() { 338 | mockVoidResult(true); 339 | when(mockFirebaseUser.updatePassword("password")).thenReturn(mockVoidTaskResult); 340 | 341 | TestObserver obs = TestObserver.create(); 342 | 343 | RxFirebaseUser.updatePassword(mockFirebaseUser, "password").subscribe(obs); 344 | 345 | callOnComplete(mockVoidTaskResult); 346 | obs.dispose(); 347 | 348 | // Ensure no more values are emitted after unsubscribe 349 | callOnComplete(mockVoidTaskResult); 350 | 351 | obs.assertNoErrors(); 352 | obs.assertComplete(); 353 | } 354 | 355 | @Test public void testUpdatePassword_notSuccessful() { 356 | mockNotSuccessfulVoidResult(new IllegalStateException()); 357 | when(mockFirebaseUser.updatePassword("password")).thenReturn(mockVoidTaskResult); 358 | 359 | TestObserver obs = TestObserver.create(); 360 | 361 | RxFirebaseUser.updatePassword(mockFirebaseUser, "password").subscribe(obs); 362 | 363 | callOnComplete(mockVoidTaskResult); 364 | obs.dispose(); 365 | 366 | // Ensure no more values are emitted after unsubscribe 367 | callOnComplete(mockVoidTaskResult); 368 | 369 | obs.assertError(IllegalStateException.class); 370 | obs.assertNotComplete(); 371 | } 372 | 373 | @Test public void testUpdateProfile() { 374 | mockVoidResult(true); 375 | when(mockFirebaseUser.updateProfile(mockProfileChangeRequest)).thenReturn(mockVoidTaskResult); 376 | 377 | TestObserver obs = TestObserver.create(); 378 | 379 | RxFirebaseUser.updateProfile(mockFirebaseUser, mockProfileChangeRequest).subscribe(obs); 380 | 381 | callOnComplete(mockVoidTaskResult); 382 | obs.dispose(); 383 | 384 | // Ensure no more values are emitted after unsubscribe 385 | callOnComplete(mockVoidTaskResult); 386 | 387 | obs.assertNoErrors(); 388 | obs.assertComplete(); 389 | } 390 | 391 | @Test public void testUpdateProfile_notSuccessful() { 392 | mockNotSuccessfulVoidResult(new IllegalStateException()); 393 | when(mockFirebaseUser.updateProfile(mockProfileChangeRequest)).thenReturn(mockVoidTaskResult); 394 | 395 | TestObserver obs = TestObserver.create(); 396 | 397 | RxFirebaseUser.updateProfile(mockFirebaseUser, mockProfileChangeRequest).subscribe(obs); 398 | 399 | callOnComplete(mockVoidTaskResult); 400 | obs.dispose(); 401 | 402 | // Ensure no more values are emitted after unsubscribe 403 | callOnComplete(mockVoidTaskResult); 404 | 405 | obs.assertError(IllegalStateException.class); 406 | obs.assertNotComplete(); 407 | } 408 | 409 | private void mockVoidResult(boolean success) { 410 | when(mockVoidTaskResult.isSuccessful()).thenReturn(success); 411 | 412 | //noinspection unchecked 413 | when(mockVoidTaskResult.addOnCompleteListener(onComplete.capture())).thenReturn( 414 | mockVoidTaskResult); 415 | } 416 | 417 | private void mockSuccessfulTokenResult(String token) { 418 | when(mockGetTokenResult.getToken()).thenReturn(token); 419 | 420 | when(mockGetTokenTaskResult.isSuccessful()).thenReturn(true); 421 | 422 | when(mockGetTokenTaskResult.getResult()).thenReturn(mockGetTokenResult); 423 | 424 | //noinspection unchecked 425 | when(mockGetTokenTaskResult.addOnCompleteListener(onComplete.capture())).thenReturn( 426 | mockGetTokenTaskResult); 427 | } 428 | 429 | private void mockNotSuccessfulTokenResult(Exception exception) { 430 | when(mockGetTokenTaskResult.isSuccessful()).thenReturn(false); 431 | 432 | when(mockGetTokenTaskResult.getException()).thenReturn(exception); 433 | 434 | when(mockGetTokenTaskResult.getResult()).thenReturn(mockGetTokenResult); 435 | 436 | //noinspection unchecked 437 | when(mockGetTokenTaskResult.addOnCompleteListener(onComplete.capture())).thenReturn( 438 | mockGetTokenTaskResult); 439 | } 440 | 441 | private void mockSuccessfulAuthResult() { 442 | when(mockAuthTaskResult.isSuccessful()).thenReturn(true); 443 | 444 | when(mockAuthTaskResult.getResult()).thenReturn(mockAuthResult); 445 | 446 | //noinspection unchecked 447 | when(mockAuthTaskResult.addOnCompleteListener(onComplete.capture())).thenReturn( 448 | mockAuthTaskResult); 449 | } 450 | 451 | private void mockNotSuccessfulAuthResult(Exception exception) { 452 | when(mockAuthTaskResult.isSuccessful()).thenReturn(false); 453 | 454 | when(mockAuthTaskResult.getException()).thenReturn(exception); 455 | 456 | when(mockAuthTaskResult.getResult()).thenReturn(mockAuthResult); 457 | 458 | //noinspection unchecked 459 | when(mockAuthTaskResult.addOnCompleteListener(onComplete.capture())).thenReturn( 460 | mockAuthTaskResult); 461 | } 462 | 463 | private void mockNotSuccessfulVoidResult(Exception exception) { 464 | when(mockVoidTaskResult.isSuccessful()).thenReturn(false); 465 | 466 | when(mockVoidTaskResult.getException()).thenReturn(exception); 467 | } 468 | 469 | @SuppressWarnings("unchecked") private void callOnComplete(Task task) { 470 | verify(task).addOnCompleteListener(onComplete.capture()); 471 | onComplete.getValue().onComplete(task); 472 | } 473 | } 474 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RxFirebase2 2 | 3 | RxJava 2 binding APIs for [Firebase](https://firebase.google.com/) Android SDK 4 | based on [RxFirebase](https://github.com/kunny/RxFirebase). 5 | 6 | ## RxJava Version 7 | 8 | It supports RxJava 2.x. 9 | 10 | ## Modules 11 | 12 | ### firebase-auth 13 | 14 | RxJava binding APIs for [Firebase Authentication](https://firebase.google.com/docs/auth/). 15 | 16 | ```groovy 17 | compile ('com.github.b3er.rxfirebase:firebase-auth:11.2.0') { 18 | transitive = false 19 | } 20 | ``` 21 | 22 | ### firebase-auth-kotlin 23 | 24 | Kotlin support module for `firebase-auth`. 25 | 26 | ```groovy 27 | compile ('com.github.b3er.rxfirebase:firebase-auth-kotlin:11.2.0') { 28 | transitive = false 29 | } 30 | ``` 31 | 32 | ### firebase-database 33 | 34 | RxJava binding APIs for [Firebase Realtime Database](https://firebase.google.com/docs/database/) Android SDK. 35 | 36 | ```groovy 37 | compile ('com.github.b3er.rxfirebase:firebase-database:11.2.0') { 38 | transitive = false 39 | } 40 | ``` 41 | 42 | ### firebase-database-kotlin 43 | 44 | Kotlin support module for `firebase-database` 45 | 46 | ```groovy 47 | compile ('com.github.b3er.rxfirebase:firebase-database-kotlin:11.2.0') { 48 | transitive = false 49 | } 50 | ``` 51 | 52 | ### firebase-storage 53 | 54 | RxJava binding APIs for [Firebase Storage](https://firebase.google.com/docs/storage/) Android SDK. 55 | 56 | ```groovy 57 | compile ('com.github.b3er.rxfirebase:firebase-storage:11.2.0') { 58 | transitive = false 59 | } 60 | ``` 61 | 62 | ### firebase-storage-kotlin 63 | 64 | Kotlin support module for `firebase-storage` 65 | 66 | ```groovy 67 | compile ('com.github.b3er.rxfirebase:firebase-storage-kotlin:11.2.0') { 68 | transitive = false 69 | } 70 | ``` 71 | 72 | Each kotlin support module maps all methods in Java module into an extension function on following classes: 73 | 74 | - firebase-auth-kotlin 75 | - `FirebaseAuth` 76 | - `FirebaseUser` 77 | - firebase-database-kotlin 78 | - `DatabaseReference` 79 | - firebase-storage-kotlin 80 | - `StorageReference` 81 | 82 | Basically, extension function has same name of methods in `RxXXX` classes in Java module. 83 | 84 | If extension function conflicts with a method in a class that is being extended, it will be renamed with `rx` prefix. 85 | 86 | For more details, please refer to following 'Usage' section. 87 | 88 | ## Usage 89 | 90 | Here are some usages of `RxFirebase2`. Since it provides just a wrapper for Firebase Android SDK, see [official documentation](https://firebase.google.com/docs/) for the details. 91 | 92 | ### Firebase Authentication 93 | 94 | #### Get the currently signed-in user (Listener) 95 | 96 | Get currently signed-in user by `Firebasebase.AuthStateChangeListener`. 97 | 98 | As a listener, it will emit `FirebaseAuth` object on each auth state changes until unsubscribed. 99 | 100 | Note that `RxFirebaseAuth.authStateChanges()` will emit initial value on subscribe. 101 | 102 | Java: 103 | ```java 104 | RxFirebaseAuth.authStateChanges(FirebaseAuth.getInstance()).subscribe( 105 | new Consumer() { 106 | @Override 107 | public void accept(FirebaseAuth firebaseAuth) throws Exception { 108 | // Do something when auth state changes. 109 | } 110 | }, new Consumer() { 111 | @Override 112 | public void accept(Throwable throwable) throws Exception { 113 | // Handle error 114 | } 115 | }); 116 | ``` 117 | 118 | Kotlin: 119 | ```kotlin 120 | FirebaseAuth.getInstance().authStateChanges() 121 | .subscribe({ 122 | // Do something when auth state changes. 123 | }, { 124 | // Handle error 125 | }) 126 | ``` 127 | 128 | #### Get the currently signed-in user (getCurrentUser()) 129 | 130 | Since `FirebaseAuth.getCurrentUser()` might return null when auth object has not finished initializing, it returns `Optional` wrapper of `FirebaseUser` object to prevent null pointer exception. 131 | 132 | Java: 133 | ```java 134 | RxFirebaseAuth.getCurrentUser(FirebaseAuth.getInstance()) 135 | .subscribe(new Consumer>() { 136 | @Override 137 | public void accept(Optional user) 138 | throws Exception { 139 | if (user.isPresent()) { 140 | // Do something with user 141 | } else { 142 | // There is not signed in user or 143 | // Firebase instance was not fully initialized. 144 | } 145 | } 146 | }, new Consumer() { 147 | @Override 148 | public void accept(Throwable throwable) throws Exception { 149 | // Handle error 150 | } 151 | }); 152 | ``` 153 | 154 | 155 | Kotlin: 156 | ```kotlin 157 | FirebaseAuth.getInstance().rxGetCurrentUser() 158 | .subscribe({ 159 | if (user.isPresent) { 160 | // Do something with user 161 | } else { 162 | // There is not signed in user or 163 | // Firebase instance was not fully initialized. 164 | } 165 | }, { 166 | // Handle error 167 | }) 168 | ``` 169 | 170 | #### Sign in anonymously 171 | 172 | Uses [Anonymous Authentication](https://firebase.google.com/docs/auth/android/anonymous-auth) for sign in. Note that it emits `FirebaseUser` object of currently signed-in user. 173 | 174 | Java: 175 | ```java 176 | RxFirebaseAuth.signInAnonymous(FirebaseAuth.getInstance()) 177 | .subscribe(new Consumer() { 178 | @Override 179 | public void accept(FirebaseUser firebaseUser) throws Exception { 180 | // Do something with anonymous user 181 | } 182 | }, new Consumer() { 183 | @Override 184 | public void accept(Throwable throwable) throws Exception { 185 | // Handle error 186 | } 187 | }); 188 | ``` 189 | 190 | Kotlin: 191 | ```kotlin 192 | FirebaseAuth.getInstance().rxSignInAnonymous() 193 | .subscribe({ 194 | // Do something with anonymous user 195 | }, { 196 | // Handle error 197 | }) 198 | ``` 199 | 200 | #### Update a user's profile 201 | 202 | For a method which returns `Task` as a result, `Completable` is used. 203 | 204 | Java: 205 | ```java 206 | FirebaseUser user = ...; 207 | 208 | UserProfileChangeRequest request = new UserProfileChangeRequest.Builder() 209 | .setDisplayName("John Doe") 210 | .setPhotoUri(Uri.parse("http://my.photo/johndoe")) 211 | .build(); 212 | 213 | RxFirebaseUser.updateProfile(user, request) 214 | .subscribe(new Action() { 215 | @Override 216 | public void run() throws Exception { 217 | // Update successful 218 | } 219 | }, new Consumer() { 220 | @Override 221 | public void accept(Throwable throwable) throws Exception { 222 | // Update was not successful 223 | } 224 | }); 225 | ``` 226 | 227 | Kotlin: 228 | ```kotlin 229 | val user: FirebaseUser = ... 230 | 231 | val request = UserProfileChangeRequest.Builder() 232 | .setDisplayName("John Doe") 233 | .setPhotoUri(Uri.parse("http://my.photo/johndoe")) 234 | .build() 235 | 236 | user.rxUpdateProfile(request) 237 | .subscribe({ 238 | // Update successful 239 | }, { 240 | // Handle error 241 | }) 242 | ``` 243 | 244 | ### Firebase Realtime Database 245 | 246 | #### Write to your database 247 | 248 | Retrieve an instance of your database using `FirebaseDatabase.getInstance()` and pass the reference of the location to `RxFirebase.setValue()` with a value. 249 | 250 | Java: 251 | 252 | ```java 253 | DatabaseReference ref = ...; 254 | 255 | RxFirebaseDatabase.setValue(ref, "Lorem ipsum") 256 | .subscribe(new Action() { 257 | @Override 258 | public void run() throws Exception { 259 | // Update successful 260 | } 261 | }, new Consumer() { 262 | @Override 263 | public void accept(Throwable throwable) throws Exception { 264 | // Something went wrong 265 | } 266 | }); 267 | ``` 268 | 269 | Kotlin: 270 | 271 | ```kotlin 272 | val ref: DatabaseReference = ...; 273 | ref.rxSetValue("Lorem ipsum") 274 | .subscribe({ 275 | // Update successful 276 | }, { 277 | // Handle error 278 | }) 279 | ``` 280 | 281 | #### Update specific fields 282 | 283 | To simultaneously write to specific children of a note without overwriting other child nodes, use the `RxFirebase.updateChildren()` method. 284 | 285 | Java: 286 | 287 | ```java 288 | DatabaseReference ref = ...; 289 | 290 | Map update = new HashMap<>(); 291 | update.put("/posts/foo", /* Post values */); 292 | update.put("/user-posts/bar", /* Post values */); 293 | 294 | RxFirebaseDatabase.updateChildren(ref, update) 295 | .subscribe(new Action() { 296 | @Override 297 | public void run() throws Exception { 298 | // Update successful 299 | } 300 | }, new Consumer() { 301 | @Override 302 | public void accept(Throwable throwable) throws Exception { 303 | // Something went wrong 304 | } 305 | }); 306 | ``` 307 | Kotlin: 308 | 309 | ```kotlin 310 | val ref: DatabaseReference = FirebaseDatabase.getInstance().getReference() 311 | 312 | val update = mapOf( 313 | "/posts/foo" to /* Post values */, 314 | "user-posts/bar" to /* Post values */) 315 | 316 | ref.rxUpdateChildren(update) 317 | .subscribe({ 318 | // Update successful 319 | }, { 320 | // Handle error 321 | }) 322 | ``` 323 | 324 | ### Read from your database 325 | 326 | #### Listen for value events 327 | 328 | You can use the `RxFirebase.dataChanges()` method to get a snapshot(`DataSnapshot`) of the contents at a given path, as they existed at the time of the event. 329 | 330 | This method will emit an event once when subscribed, and again every time the data, including children, changes. 331 | 332 | Java: 333 | 334 | ```java 335 | DatabaseReference ref = ...; 336 | 337 | RxFirebaseDatabase.dataChanges(ref) 338 | .subscribe(new Consumer() { 339 | @Override 340 | public void accept(DataSnapshot dataSnapshot) throws Exception { 341 | if (dataSnapshot.exists()) { 342 | // Do something with data 343 | } else { 344 | // Data does not exists 345 | } 346 | } 347 | }, new Consumer() { 348 | @Override 349 | public void accept(Throwable throwable) throws Exception { 350 | // Handle error 351 | } 352 | }); 353 | ``` 354 | 355 | Kotlin: 356 | 357 | ```kotlin 358 | val ref: DatabaseReference = ... 359 | 360 | ref.dataChanges() 361 | .subscribe({ 362 | if (it.exists()) { 363 | // Do something with data 364 | } else { 365 | // Data does not exists 366 | } 367 | }) { 368 | // Handle error 369 | } 370 | ``` 371 | 372 | If you want to get a data as a native object, you can use `RxFirebaseDatabase.dataChangesOf(Class)` or `RxFirebaseDatabase.dataChangesOf(GenericTypeIndicator)`. 373 | 374 | You *must* unsubscribe a subscription once you're done with listening value events to prevent memory leak. 375 | 376 | #### Listen for child events 377 | 378 | Child events are trigger in response to specific operations that happen to the children of a node from an operation such as a new child added through the `push()` method or a child being update through the `updateChildren()` method. 379 | 380 | You can listen for child events by `RxFirebaseDatabase.childEvents()` method, which emits an event as following: 381 | 382 | - `ChildAddEvent` - Emitted on `ChildEventListener.onChildAdded()` call 383 | - `ChildChangeEvent` - Emitted on `ChildEventListener.onChildChanged()` call 384 | - `ChildMoveEvent` - Emitted on `ChildEventListener.onChildMoved()` call 385 | - `ChildRemoveEvent` - Emitted on `ChildEventListener.onChildRemoved()` call 386 | 387 | `RxFirebaseDatabase.childEvents()` will emit all types of event by default. If you need to listen for specific event, you can filter by using `ofType()` operator in `RxJava` as following: 388 | 389 | Java: 390 | 391 | ```java 392 | DatabaseReference ref = ...; 393 | 394 | RxFirebaseDatabase.childEvents(ref) 395 | .ofType(ChildAddEvent.class) 396 | .subscribe(new Consumer() { 397 | @Override 398 | public void accept(ChildAddEvent childAddEvent) throws Exception { 399 | // Handle for Child add event 400 | } 401 | }, new Consumer() { 402 | @Override 403 | public void accept(Throwable throwable) throws Exception { 404 | // Handle error 405 | } 406 | }); 407 | ``` 408 | 409 | Kotlin: 410 | 411 | ```kotlin 412 | val ref: DatabaseReference = ... 413 | 414 | ref.childEvents() 415 | .ofType(ChildAddEvent::class.java) 416 | .subscribe({ 417 | // Handle for child add event 418 | }) { 419 | // Handle error 420 | } 421 | ``` 422 | 423 | You *must* unsubscribe a subscription once you're done with listening child events to prevent memory leak. 424 | 425 | #### Read data once 426 | 427 | This is useful for data that only needs to be loaded once and isn't expected to change frequently or require active listening. 428 | 429 | Similar to listening for the data changes, you can use `RxFirebaseDatabase.data()` method to get an `Optional` wrapper of static snapshot of the contents. 430 | 431 | Java: 432 | 433 | ```java 434 | DatabaseReference ref = ...; 435 | 436 | RxFirebaseDatabase.data(ref) 437 | .subscribe(new Action1() { 438 | @Override 439 | public void call(DataSnapshot dataSnapshot) { 440 | if (dataSnapshot.exists()) { 441 | // Do something with data 442 | } else { 443 | // Data does not exists 444 | } 445 | } 446 | }, new Action1() { 447 | @Override 448 | public void call(Throwable throwable) { 449 | // Handle error 450 | } 451 | }); 452 | ``` 453 | 454 | Kotlin: 455 | 456 | ```kotlin 457 | val ref: DatabaseReference = FirebaseDatabase.getInstance().getReference() 458 | 459 | ref.data() 460 | .subscribe({ 461 | if (it.exists()) { 462 | // Do something with data 463 | } else { 464 | // Data does not exists 465 | } 466 | }) { 467 | // Handle error 468 | } 469 | ``` 470 | 471 | ## Versioning 472 | 473 | RxFirebase2 uses a versioning rule that is related to corresponding Firebase's version by following rule: 474 | 475 | ``` 476 | RxFirebaseVersion : {major}.{minor}.{patch} = 477 | {Firebase major}.{Firebase minor * 10 + Firebase patch}.{RxFirebase patch} 478 | ``` 479 | 480 | For example, a library version that depends on `9.6.0` version of Firebase SDK, whose patch version is `1` will be `9.60.1`. 481 | 482 | ## Development Snapshot 483 | 484 | Snapshots of the development version are available in [Sonatype's `snapshots` repository](Sonatype's snapshots repository). 485 | 486 | You can register snapshots repo as your project's remote repo as following: 487 | 488 | ```groovy 489 | repositories { 490 | ... other remote repositories ... 491 | 492 | // Add following line 493 | maven { url "https://oss.sonatype.org/content/repositories/snapshots/" } 494 | } 495 | ``` 496 | 497 | Currently, there is no snapshot available. 498 | 499 | ## License 500 | 501 | ``` 502 | Copyright 2017 Ilya Usanov 503 | 504 | Licensed under the Apache License, Version 2.0 (the "License"); 505 | you may not use this file except in compliance with the License. 506 | You may obtain a copy of the License at 507 | 508 | http://www.apache.org/licenses/LICENSE-2.0 509 | 510 | Unless required by applicable law or agreed to in writing, software 511 | distributed under the License is distributed on an "AS IS" BASIS, 512 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 513 | See the License for the specific language governing permissions and 514 | limitations under the License. 515 | ``` -------------------------------------------------------------------------------- /firebase-database/src/test/java/com/github/b3er/rxfirebase/database/RxFirebaseDatabaseTest.java: -------------------------------------------------------------------------------- 1 | package com.github.b3er.rxfirebase.database; 2 | 3 | import com.google.android.gms.tasks.OnCompleteListener; 4 | import com.google.android.gms.tasks.Task; 5 | import com.google.firebase.database.ChildEventListener; 6 | import com.google.firebase.database.DataSnapshot; 7 | import com.google.firebase.database.DatabaseError; 8 | import com.google.firebase.database.DatabaseException; 9 | import com.google.firebase.database.DatabaseReference; 10 | import com.google.firebase.database.GenericTypeIndicator; 11 | import com.google.firebase.database.MutableData; 12 | import com.google.firebase.database.Transaction; 13 | import com.google.firebase.database.ValueEventListener; 14 | import com.memoizrlabs.retrooptional.Optional; 15 | import io.reactivex.functions.Function; 16 | import io.reactivex.functions.Predicate; 17 | import io.reactivex.observers.TestObserver; 18 | import java.util.ArrayList; 19 | import java.util.HashMap; 20 | import java.util.List; 21 | import java.util.Map; 22 | import org.junit.Before; 23 | import org.junit.Test; 24 | import org.mockito.ArgumentCaptor; 25 | import org.mockito.Mock; 26 | import org.mockito.MockitoAnnotations; 27 | 28 | import static org.assertj.core.api.Assertions.assertThat; 29 | import static org.mockito.Matchers.anyBoolean; 30 | import static org.mockito.Mockito.verify; 31 | import static org.mockito.Mockito.when; 32 | 33 | public class RxFirebaseDatabaseTest { 34 | 35 | @Mock DatabaseReference mockDatabaseReference; 36 | 37 | @Mock DataSnapshot mockDataSnapshot; 38 | 39 | @Mock DatabaseError mockDatabaseError; 40 | 41 | @Mock MutableData mockMutableData; 42 | 43 | @Mock Function mockTransactionTask; 44 | 45 | @Mock Task mockTask; 46 | 47 | private ArgumentCaptor childEventListener; 48 | 49 | private ArgumentCaptor valueEventListener; 50 | 51 | private ArgumentCaptor transactionHandler; 52 | 53 | private ArgumentCaptor onCompleteListener; 54 | 55 | @Before public void setup() { 56 | MockitoAnnotations.initMocks(this); 57 | 58 | childEventListener = ArgumentCaptor.forClass(ChildEventListener.class); 59 | valueEventListener = ArgumentCaptor.forClass(ValueEventListener.class); 60 | transactionHandler = ArgumentCaptor.forClass(Transaction.Handler.class); 61 | onCompleteListener = ArgumentCaptor.forClass(OnCompleteListener.class); 62 | } 63 | 64 | @Test public void testChildEvents_add() { 65 | TestObserver sub = TestObserver.create(); 66 | 67 | RxFirebaseDatabase.childEvents(mockDatabaseReference).subscribe(sub); 68 | 69 | verifyAddChildEventListener(); 70 | callOnChildAdded("foo"); 71 | callOnChildAdded("foo"); 72 | 73 | sub.assertNotComplete(); 74 | sub.assertNoErrors(); 75 | sub.assertValueCount(2); 76 | 77 | List events = sub.getEvents().get(0); 78 | for (Object event : events) { 79 | assertThat(event).isInstanceOf(ChildEvent.class); 80 | assertThat(event).isInstanceOf(ChildAddEvent.class); 81 | assertThat(((ChildAddEvent) event).previousChildName()).isEqualTo("foo"); 82 | } 83 | 84 | sub.dispose(); 85 | 86 | callOnChildAdded("baz"); 87 | 88 | // Ensure no more values are emitted after unsubscrube 89 | sub.assertValueCount(2); 90 | } 91 | 92 | @Test public void testChildEvents_change() { 93 | TestObserver sub = TestObserver.create(); 94 | 95 | RxFirebaseDatabase.childEvents(mockDatabaseReference).subscribe(sub); 96 | 97 | verifyAddChildEventListener(); 98 | callOnChildChanged("foo"); 99 | callOnChildChanged("foo"); 100 | 101 | sub.assertNotComplete(); 102 | sub.assertNoErrors(); 103 | sub.assertValueCount(2); 104 | 105 | List events = sub.getEvents().get(0); 106 | for (Object event : events) { 107 | assertThat(event).isInstanceOf(ChildEvent.class); 108 | assertThat(event).isInstanceOf(ChildChangeEvent.class); 109 | assertThat(((ChildChangeEvent) event).previousChildName()).isEqualTo("foo"); 110 | } 111 | 112 | sub.dispose(); 113 | 114 | callOnChildChanged("foo"); 115 | 116 | // Ensure no more values are emitted after unsubscrube 117 | sub.assertValueCount(2); 118 | } 119 | 120 | @Test public void testChildEvents_remove() { 121 | TestObserver sub = TestObserver.create(); 122 | 123 | RxFirebaseDatabase.childEvents(mockDatabaseReference).subscribe(sub); 124 | 125 | verifyAddChildEventListener(); 126 | callOnChildRemoved(); 127 | callOnChildRemoved(); 128 | 129 | sub.assertNotComplete(); 130 | sub.assertNoErrors(); 131 | sub.assertValueCount(2); 132 | 133 | List events = sub.getEvents().get(0); 134 | for (Object event : events) { 135 | assertThat(event).isInstanceOf(ChildEvent.class); 136 | assertThat(event).isInstanceOf(ChildRemoveEvent.class); 137 | } 138 | 139 | sub.dispose(); 140 | 141 | callOnChildRemoved(); 142 | 143 | // Ensure no more values are emitted after unsubscrube 144 | sub.assertValueCount(2); 145 | } 146 | 147 | @Test public void testChildEvents_move() { 148 | TestObserver sub = TestObserver.create(); 149 | 150 | RxFirebaseDatabase.childEvents(mockDatabaseReference).subscribe(sub); 151 | 152 | verifyAddChildEventListener(); 153 | callOnChildMoved("foo"); 154 | callOnChildMoved("foo"); 155 | 156 | sub.assertNotComplete(); 157 | sub.assertNoErrors(); 158 | sub.assertValueCount(2); 159 | 160 | List events = sub.getEvents().get(0); 161 | for (Object event : events) { 162 | assertThat(event).isInstanceOf(ChildEvent.class); 163 | assertThat(event).isInstanceOf(ChildMoveEvent.class); 164 | assertThat(((ChildMoveEvent) event).previousChildName()).isEqualTo("foo"); 165 | } 166 | 167 | sub.dispose(); 168 | 169 | callOnChildMoved("foo"); 170 | 171 | // Ensure no more values are emitted after unsubscrube 172 | sub.assertValueCount(2); 173 | } 174 | 175 | @Test public void testChildEvents_notSuccessful() { 176 | TestObserver sub = TestObserver.create(); 177 | 178 | RxFirebaseDatabase.childEvents(mockDatabaseReference).subscribe(sub); 179 | 180 | verifyAddChildEventListener(); 181 | callChildOnCancelled(); 182 | 183 | sub.assertNoValues(); 184 | assertThat(sub.errorCount()).isEqualTo(1); 185 | 186 | sub.dispose(); 187 | 188 | callChildOnCancelled(); 189 | 190 | // Ensure no more values are emitted after unsubscribe 191 | assertThat(sub.errorCount()).isEqualTo(1); 192 | } 193 | 194 | @Test public void testData() { 195 | TestObserver sub = TestObserver.create(); 196 | 197 | RxFirebaseDatabase.data(mockDatabaseReference).subscribe(sub); 198 | 199 | verifyAddListenerForSingleValueEvent(); 200 | callValueEventOnDataChange("Foo"); 201 | sub.dispose(); 202 | 203 | // Ensure no more values are emitted after unsubscribe 204 | callValueEventOnDataChange("Foo"); 205 | 206 | sub.assertNoErrors(); 207 | sub.assertComplete(); 208 | sub.assertValueCount(1); 209 | } 210 | 211 | @Test public void testData_onCancelled() { 212 | TestObserver sub = TestObserver.create(); 213 | 214 | RxFirebaseDatabase.data(mockDatabaseReference).subscribe(sub); 215 | 216 | verifyAddListenerForSingleValueEvent(); 217 | callValueEventOnCancelled(new DatabaseException("foo")); 218 | 219 | sub.assertError(DatabaseException.class); 220 | sub.assertNoValues(); 221 | 222 | sub.dispose(); 223 | 224 | callValueEventOnCancelled(new DatabaseException("foo")); 225 | 226 | // Ensure no more values are emitted after unsubscribe 227 | assertThat(sub.errorCount()).isEqualTo(1); 228 | } 229 | 230 | @Test public void testDataChanges() { 231 | TestObserver sub = TestObserver.create(); 232 | 233 | RxFirebaseDatabase.dataChanges(mockDatabaseReference).subscribe(sub); 234 | 235 | verifyAddValueEventListener(); 236 | callValueEventOnDataChange("Foo"); 237 | 238 | sub.assertNotComplete(); 239 | sub.assertValueCount(1); 240 | 241 | sub.dispose(); 242 | 243 | callValueEventOnDataChange("Foo"); 244 | 245 | // Ensure no more values are emitted after unsubscribe 246 | sub.assertValueCount(1); 247 | } 248 | 249 | @Test public void testDataChanges_onCancelled() { 250 | TestObserver sub = TestObserver.create(); 251 | 252 | RxFirebaseDatabase.dataChanges(mockDatabaseReference).subscribe(sub); 253 | 254 | verifyAddValueEventListener(); 255 | callValueEventOnCancelled(new DatabaseException("foo")); 256 | 257 | sub.assertError(DatabaseException.class); 258 | sub.assertNoValues(); 259 | 260 | sub.dispose(); 261 | 262 | callValueEventOnCancelled(new DatabaseException("foo")); 263 | 264 | // Ensure no more values are emitted after unsubscribe 265 | assertThat(sub.errorCount()).isEqualTo(1); 266 | } 267 | 268 | @Test public void testDataChangesOfClazz() { 269 | TestObserver> sub = TestObserver.create(); 270 | 271 | RxFirebaseDatabase.dataChangesOf(mockDatabaseReference, String.class).subscribe(sub); 272 | 273 | verifyAddValueEventListener(); 274 | callValueEventOnDataChange("Foo"); 275 | 276 | sub.assertNotComplete(); 277 | sub.assertValueCount(1); 278 | sub.assertValue(new Predicate>() { 279 | @Override public boolean test(Optional stringOptional) throws Exception { 280 | return stringOptional.isPresent() && "Foo".equals(stringOptional.get()); 281 | } 282 | }); 283 | 284 | sub.dispose(); 285 | 286 | callValueEventOnDataChange("Foo"); 287 | 288 | // Ensure no more values are emitted after unsubscribe 289 | sub.assertValueCount(1); 290 | } 291 | 292 | @Test public void testDataChangesOfGenericTypeIndicator() { 293 | List values = new ArrayList<>(); 294 | values.add("Foo"); 295 | values.add("Bar"); 296 | 297 | GenericTypeIndicator> typeIndicator = new GenericTypeIndicator>() { 298 | }; 299 | 300 | TestObserver>> sub = TestObserver.create(); 301 | 302 | RxFirebaseDatabase.dataChangesOf(mockDatabaseReference, typeIndicator).subscribe(sub); 303 | 304 | verifyAddValueEventListener(); 305 | callValueEventOnDataChange(typeIndicator, values); 306 | 307 | sub.assertNotComplete(); 308 | 309 | sub.assertValue(new Predicate>>() { 310 | @Override public boolean test(Optional> listOptional) throws Exception { 311 | return listOptional.isPresent() && "Foo".equals(listOptional.get().get(0)) && "Bar".equals( 312 | listOptional.get().get(1)); 313 | } 314 | }); 315 | 316 | sub.dispose(); 317 | 318 | callValueEventOnDataChange(typeIndicator, values); 319 | 320 | // Ensure no more values are emitted after unsubscribe 321 | sub.assertValueCount(1); 322 | } 323 | 324 | @Test public void testDataOfClazz() { 325 | TestObserver> sub = TestObserver.create(); 326 | 327 | RxFirebaseDatabase.dataOf(mockDatabaseReference, String.class).subscribe(sub); 328 | 329 | verifyAddListenerForSingleValueEvent(); 330 | callValueEventOnDataChange("Foo"); 331 | 332 | sub.assertComplete(); 333 | sub.assertNoErrors(); 334 | 335 | sub.assertValue(new Predicate>() { 336 | @Override public boolean test(Optional stringOptional) throws Exception { 337 | return stringOptional.isPresent() && "Foo".equals(stringOptional.get()); 338 | } 339 | }); 340 | 341 | sub.dispose(); 342 | 343 | callValueEventOnDataChange("Foo"); 344 | 345 | // Ensure no more values are emitted after unsubscribe 346 | sub.assertValueCount(1); 347 | } 348 | 349 | @Test public void testDataOfGenericTypeIndicator() { 350 | List values = new ArrayList<>(); 351 | values.add("Foo"); 352 | values.add("Bar"); 353 | 354 | GenericTypeIndicator> typeIndicator = new GenericTypeIndicator>() { 355 | }; 356 | 357 | TestObserver>> sub = TestObserver.create(); 358 | 359 | RxFirebaseDatabase.dataOf(mockDatabaseReference, typeIndicator).subscribe(sub); 360 | 361 | verifyAddListenerForSingleValueEvent(); 362 | callValueEventOnDataChange(typeIndicator, values); 363 | 364 | sub.assertComplete(); 365 | sub.assertNoErrors(); 366 | 367 | sub.assertValue(new Predicate>>() { 368 | @Override public boolean test(Optional> listOptional) throws Exception { 369 | return listOptional.isPresent() && "Foo".equals(listOptional.get().get(0)) && "Bar".equals( 370 | listOptional.get().get(1)); 371 | } 372 | }); 373 | 374 | sub.dispose(); 375 | 376 | callValueEventOnDataChange(typeIndicator, values); 377 | 378 | // Ensure no more values are emitted after unsubscribe 379 | sub.assertValueCount(1); 380 | } 381 | 382 | @Test public void testRemoveValue() { 383 | when(mockDatabaseReference.removeValue()).thenReturn(mockTask); 384 | 385 | TestObserver sub = TestObserver.create(); 386 | 387 | RxFirebaseDatabase.removeValue(mockDatabaseReference).subscribe(sub); 388 | 389 | verifyAddOnCompleteListenerForTask(); 390 | callTaskOnComplete(); 391 | 392 | sub.assertComplete(); 393 | sub.assertNoErrors(); 394 | 395 | sub.dispose(); 396 | } 397 | 398 | @Test public void testRemoveValue_Unsuccessful() { 399 | when(mockDatabaseReference.removeValue()).thenReturn(mockTask); 400 | 401 | TestObserver sub = TestObserver.create(); 402 | 403 | RxFirebaseDatabase.removeValue(mockDatabaseReference).subscribe(sub); 404 | 405 | verifyAddOnCompleteListenerForTask(); 406 | callTaskOnCompleteWithError(new IllegalStateException()); 407 | 408 | sub.assertNotComplete(); 409 | sub.assertError(IllegalStateException.class); 410 | 411 | sub.dispose(); 412 | } 413 | 414 | @Test public void testSetPriority() { 415 | when(mockDatabaseReference.setPriority(1)).thenReturn(mockTask); 416 | 417 | TestObserver sub = TestObserver.create(); 418 | 419 | RxFirebaseDatabase.setPriority(mockDatabaseReference, 1).subscribe(sub); 420 | 421 | verifyAddOnCompleteListenerForTask(); 422 | callTaskOnComplete(); 423 | 424 | sub.assertComplete(); 425 | sub.assertNoErrors(); 426 | 427 | sub.dispose(); 428 | } 429 | 430 | @Test public void testSetPriority_notSuccessful() { 431 | when(mockDatabaseReference.setPriority(1)).thenReturn(mockTask); 432 | 433 | TestObserver sub = TestObserver.create(); 434 | 435 | RxFirebaseDatabase.setPriority(mockDatabaseReference, 1).subscribe(sub); 436 | 437 | verifyAddOnCompleteListenerForTask(); 438 | callTaskOnCompleteWithError(new IllegalStateException()); 439 | 440 | sub.assertNotComplete(); 441 | sub.assertError(IllegalStateException.class); 442 | } 443 | 444 | @Test public void testSetValue() { 445 | when(mockDatabaseReference.setValue(1)).thenReturn(mockTask); 446 | 447 | TestObserver sub = TestObserver.create(); 448 | 449 | RxFirebaseDatabase.setValue(mockDatabaseReference, 1).subscribe(sub); 450 | 451 | verifyAddOnCompleteListenerForTask(); 452 | callTaskOnComplete(); 453 | 454 | sub.assertComplete(); 455 | sub.assertNoErrors(); 456 | sub.dispose(); 457 | } 458 | 459 | @Test public void testSetValue_notSuccessful() { 460 | when(mockDatabaseReference.setValue(1)).thenReturn(mockTask); 461 | 462 | TestObserver sub = TestObserver.create(); 463 | 464 | RxFirebaseDatabase.setValue(mockDatabaseReference, 1).subscribe(sub); 465 | 466 | verifyAddOnCompleteListenerForTask(); 467 | callTaskOnCompleteWithError(new IllegalStateException()); 468 | 469 | sub.assertNotComplete(); 470 | sub.assertError(IllegalStateException.class); 471 | } 472 | 473 | @Test public void testSetValueWithPriority() { 474 | when(mockDatabaseReference.setValue(1, 1)).thenReturn(mockTask); 475 | 476 | TestObserver sub = TestObserver.create(); 477 | 478 | RxFirebaseDatabase.setValue(mockDatabaseReference, 1, 1).subscribe(sub); 479 | 480 | verifyAddOnCompleteListenerForTask(); 481 | callTaskOnComplete(); 482 | 483 | sub.assertComplete(); 484 | sub.assertNoErrors(); 485 | sub.dispose(); 486 | } 487 | 488 | @Test public void testSetValueWithPriority_notSuccessful() { 489 | when(mockDatabaseReference.setValue(1, 1)).thenReturn(mockTask); 490 | 491 | TestObserver sub = TestObserver.create(); 492 | 493 | RxFirebaseDatabase.setValue(mockDatabaseReference, 1, 1).subscribe(sub); 494 | 495 | verifyAddOnCompleteListenerForTask(); 496 | callTaskOnCompleteWithError(new IllegalStateException()); 497 | 498 | sub.assertNotComplete(); 499 | sub.assertError(IllegalStateException.class); 500 | sub.dispose(); 501 | } 502 | 503 | @Test public void testUpdateChildren() { 504 | Map map = new HashMap<>(); 505 | 506 | when(mockDatabaseReference.updateChildren(map)).thenReturn(mockTask); 507 | 508 | TestObserver sub = TestObserver.create(); 509 | 510 | RxFirebaseDatabase.updateChildren(mockDatabaseReference, map).subscribe(sub); 511 | 512 | verifyAddOnCompleteListenerForTask(); 513 | callTaskOnComplete(); 514 | 515 | sub.assertComplete(); 516 | sub.assertNoErrors(); 517 | sub.dispose(); 518 | } 519 | 520 | @Test public void testUpdateChildren_notSuccessful() { 521 | Map map = new HashMap<>(); 522 | 523 | when(mockDatabaseReference.updateChildren(map)).thenReturn(mockTask); 524 | 525 | TestObserver sub = TestObserver.create(); 526 | 527 | RxFirebaseDatabase.updateChildren(mockDatabaseReference, map).subscribe(sub); 528 | 529 | verifyAddOnCompleteListenerForTask(); 530 | callTaskOnCompleteWithError(new IllegalStateException()); 531 | 532 | sub.assertNotComplete(); 533 | sub.assertError(IllegalStateException.class); 534 | 535 | sub.dispose(); 536 | } 537 | 538 | @Test public void testRunTransaction() throws Exception { 539 | TestObserver sub = TestObserver.create(); 540 | 541 | RxFirebaseDatabase.runTransaction(mockDatabaseReference, mockTransactionTask).subscribe(sub); 542 | 543 | verifyRunTransaction(); 544 | 545 | callTransactionOnComplete(); 546 | verifyTransactionTaskCall(); 547 | 548 | sub.assertComplete(); 549 | sub.assertNoErrors(); 550 | 551 | sub.dispose(); 552 | } 553 | 554 | @Test public void testRunTransaction_onError() { 555 | TestObserver sub = TestObserver.create(); 556 | 557 | RxFirebaseDatabase.runTransaction(mockDatabaseReference, mockTransactionTask).subscribe(sub); 558 | 559 | verifyRunTransaction(); 560 | 561 | callTransactionOnCompleteWithError(new DatabaseException("Foo")); 562 | 563 | sub.assertNotComplete(); 564 | sub.assertError(DatabaseException.class); 565 | 566 | sub.dispose(); 567 | } 568 | 569 | private void verifyAddChildEventListener() { 570 | verify(mockDatabaseReference).addChildEventListener(childEventListener.capture()); 571 | } 572 | 573 | private void verifyAddListenerForSingleValueEvent() { 574 | verify(mockDatabaseReference).addListenerForSingleValueEvent(valueEventListener.capture()); 575 | } 576 | 577 | private void verifyAddValueEventListener() { 578 | verify(mockDatabaseReference).addValueEventListener(valueEventListener.capture()); 579 | } 580 | 581 | private void verifyRunTransaction() { 582 | verify(mockDatabaseReference).runTransaction(transactionHandler.capture(), anyBoolean()); 583 | } 584 | 585 | private void verifyTransactionTaskCall() throws Exception { 586 | verify(mockTransactionTask).apply(mockMutableData); 587 | } 588 | 589 | private void verifyAddOnCompleteListenerForTask() { 590 | //noinspection unchecked 591 | verify(mockTask).addOnCompleteListener(onCompleteListener.capture()); 592 | } 593 | 594 | private void callOnChildAdded(String previousChildName) { 595 | childEventListener.getValue().onChildAdded(mockDataSnapshot, previousChildName); 596 | } 597 | 598 | private void callOnChildChanged(String previousChildName) { 599 | childEventListener.getValue().onChildChanged(mockDataSnapshot, previousChildName); 600 | } 601 | 602 | private void callOnChildMoved(String previousChildName) { 603 | childEventListener.getValue().onChildMoved(mockDataSnapshot, previousChildName); 604 | } 605 | 606 | private void callOnChildRemoved() { 607 | childEventListener.getValue().onChildRemoved(mockDataSnapshot); 608 | } 609 | 610 | private void callChildOnCancelled() { 611 | childEventListener.getValue().onCancelled(mockDatabaseError); 612 | } 613 | 614 | private void callValueEventOnDataChange(T value) { 615 | when(mockDataSnapshot.getValue(value.getClass())).thenReturn(value); 616 | 617 | valueEventListener.getValue().onDataChange(mockDataSnapshot); 618 | } 619 | 620 | private void callValueEventOnDataChange(GenericTypeIndicator type, T value) { 621 | when(mockDataSnapshot.getValue(type)).thenReturn(value); 622 | 623 | valueEventListener.getValue().onDataChange(mockDataSnapshot); 624 | } 625 | 626 | private void callValueEventOnCancelled(DatabaseException mockedException) { 627 | when(mockDatabaseError.toException()).thenReturn(mockedException); 628 | 629 | valueEventListener.getValue().onCancelled(mockDatabaseError); 630 | } 631 | 632 | private void callTransactionOnComplete() { 633 | transactionHandler.getValue().doTransaction(mockMutableData); 634 | transactionHandler.getValue().onComplete(null, true, mockDataSnapshot); 635 | } 636 | 637 | private void callTransactionOnCompleteWithError(DatabaseException mockedException) { 638 | when(mockDatabaseError.toException()).thenReturn(mockedException); 639 | 640 | transactionHandler.getValue().onComplete(mockDatabaseError, false, mockDataSnapshot); 641 | } 642 | 643 | private void callTaskOnComplete() { 644 | when(mockTask.isSuccessful()).thenReturn(true); 645 | 646 | //noinspection unchecked 647 | onCompleteListener.getValue().onComplete(mockTask); 648 | } 649 | 650 | private void callTaskOnCompleteWithError(Exception e) { 651 | when(mockTask.isSuccessful()).thenReturn(false); 652 | 653 | when(mockTask.getException()).thenReturn(e); 654 | 655 | //noinspection unchecked 656 | onCompleteListener.getValue().onComplete(mockTask); 657 | } 658 | } 659 | --------------------------------------------------------------------------------