Skip to content

Realtime Database

Taeho Kim edited this page Mar 29, 2017 · 2 revisions

Write to your database

Set a value

Retrieve an instance of your database using FirebaseDatabase.getInstance() and pass the reference of the location to RxFirebase.setValue() with a value.

RxJava 1.x

Java:

DatabaseReference ref = ...;

RxFirebaseDatabase.setValue(ref, "Lorem ipsum")
        .subscribe(new Action0() {
            @Override
            public void call() {
                // Update successful
            }
        }, new Action1<Throwable>() {
            @Override
            public void call(Throwable throwable) {
                // Something went wrong
            }
        });

Kotlin:

val ref: DatabaseReference = ...

ref.rxSetValue("Lorem ipsum")
        .subscribe({
            // Update successful
        }) {
            // Somthing went wrong
        }

RxJava 2.x

Java:

DatabaseReference ref = ...;

RxFirebaseDatabase.setValue(ref, "Lorem ipsum")
        .subscribe(new Action() {
            @Override
            public void run() {
                // Update successful
            }
        }, new Consumer<Throwable>() {
            @Override
            public void accept(Throwable throwable) {
                // Something went wrong
            }
        });

Kotlin:

val ref: DatabaseReference = ...

ref.rxSetValue("Lorem ipsum")
        .subscribe({
            // Update successful
        }) {
            // Somthing went wrong
        }

Update specific fields

To simultaneously write to specific children of a node without overwriting other child nodes, use the RxFirebase.updateChildren() method.

RxJava 1.x

Java:

DatabaseReference ref = ...;

Map<String, Object> update = new HashMap<>();
update.put("/posts/foo", /* Post values */);
update.put("/user-posts/bar", /* Post values */);

RxFirebaseDatabase.updateChildren(ref, update)
        .subscribe(new Action0() {
            @Override
            public void call() {
                // Do something with result
            }
        }, new Action1<Throwable>() {
            @Override
            public void call(Throwable throwable) {
                // Something went wrong
            }
        });

Kotlin:

val ref: DatabaseReference = FirebaseDatabase.getInstance().getReference()

val update = mapOf(
              "/posts/foo" to /* Post values */,
              "/user-posts/bar" to /* Post values */)

ref.rxUpdateChildren(update)
        .subscribe({
            // Do something with result
        }) {
            // Something went wrong
        }

RxJava 2.x

DatabaseReference ref = ...;

Map<String, Object> update = new HashMap<>();
update.put("/posts/foo", /* Post values */);
update.put("/user-posts/bar", /* Post values */);

RxFirebaseDatabase.updateChildren(ref, update)
        .subscribe(new Action() {
            @Override
            public void run() {
                // Do something with result
            }
        }, new Consumer<Throwable>() {
            @Override
            public void accept(Throwable throwable) {
                // Something went wrong
            }
        });

Kotlin:

val ref: DatabaseReference = FirebaseDatabase.getInstance().getReference()

val update = mapOf(
              "/posts/foo" to /* Post values */,
              "/user-posts/bar" to /* Post values */)

ref.rxUpdateChildren(update)
        .subscribe({
            // Do something with result
        }) {
            // Something went wrong
        }

Read from your database

Listen for value events

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.

This method will emit an event once when subscribed, and again every time the data, including children, changes.

RxJava 1.x

Java:

DatabaseReference ref = ...;

RxFirebaseDatabase.dataChanges(ref)
        .subscribe(new Action1<DataSnapshot>() {
            @Override
            public void call(DataSnapshot dataSnapshot) {
                if (dataSnapshot.exists()) {
                    // Do something with data
                } else {
                    // Data does not exists
                }
            }
        }, new Action1<Throwable>() {
            @Override
            public void call(Throwable throwable) {
                // Handle error
            }
        });

Kotlin:

val ref: DatabaseReference = ...

ref.dataChanges()
        .subscribe({
            if (it.exists()) {
                // Do something with data
            } else {
                // Data does not exists
            }
        }) {
            // Handle error
        }

RxJava 2.x

Java:

DatabaseReference ref = ...;

RxFirebaseDatabase.dataChanges(ref)
        .subscribe(new Consumer<DataSnapshot>() {
            @Override
            public void accept(DataSnapshot dataSnapshot) {
                if (dataSnapshot.exists()) {
                    // Do something with data
                } else {
                    // Data does not exists
                }
            }
        }, new Consumer<Throwable>() {
            @Override
            public void accept(Throwable throwable) {
                // Handle error
            }
        });

Kotlin:

val ref: DatabaseReference = ...

ref.dataChanges()
        .subscribe({
            if (it.exists()) {
                // Do something with data
            } else {
                // Data does not exists
            }
        }) {
            // Handle error
        }

If you want to get a data as a native object, you can use RxFirebaseDatabase.dataChangesOf(Class<T>) or RxFirebaseDatabase.dataChangesOf(GenericTypeIndicator<T>).

You must unsubscribe a subscription once you're done with listening value events to prevent a memory leak.

Listen for child events

Child events are triggered in response to specific operations that happen to the children of a node, such as a new child added through the push() method or a child being update through the updateChildren() method.

You can listen for child events by RxFirebaseDatabase.childEvents() method, which emits an event as following:

  • ChildAddEvent - Emitted on ChildEventListener.onChildAdded() call
  • ChildChangeEvent - Emitted on ChildEventListener.onChildChanged() call
  • ChildMoveEvent - Emitted on ChildEventListener.onChildMoved() call
  • ChildRemoveEvent - Emitted on ChildEventListener.onChildRemoved() call

RxFirebaseDatabase.childEvents() will emit all types of event by default. If you need to listen for a particular event, you can filter by using ofType() operator in RxJava as following:

RxJava 1.x

Java:

DatabaseReference ref = ...;

RxFirebaseDatabase.childEvents(ref)
        .ofType(ChildAddEvent.class)
        .subscribe(new Action1<ChildAddEvent>() {
            @Override
            public void call(ChildAddEvent childAddEvent) {
                // Handle for Child add event
            }
        }, new Action1<Throwable>() {
            @Override
            public void call(Throwable throwable) {
                // Handle error
            }
        });

Kotlin:

val ref: DatabaseReference = ...

ref.childEvents()
        .ofType(ChildAddEvent::class.java)
        .subscribe({
            // Handle for child add event
        }) {
            // Handle error
        }

RxJava 2.x

Java:

DatabaseReference ref = ...;

RxFirebaseDatabase.childEvents(ref)
        .ofType(ChildAddEvent.class)
        .subscribe(new Consumer<ChildAddEvent>() {
            @Override
            public void accept(ChildAddEvent childAddEvent) {
                // Handle for Child add event
            }
        }, new Consumer<Throwable>() {
            @Override
            public void accept(Throwable throwable) {
                // Handle error
            }
        });

Kotlin:

val ref: DatabaseReference = ...

ref.childEvents()
        .ofType(ChildAddEvent::class.java)
        .subscribe({
            // Handle for child add event
        }) {
            // Handle error
        }

You must unsubscribe a subscription once you're done with listening child events to prevent a memory leak.

Read data once

This is useful for data that only needs to be loaded once and isn't expected to change frequently or require active listening.

Similar to listening for the data changes, you can use RxFirebaseDatabase.data() method to get a snapshot of the content.

RxJava 1.x

Java:

DatabaseReference ref = ...;

RxFirebaseDatabase.data(ref)
        .subscribe(new Action1<DataSnapshot>() {
            @Override
            public void call(DataSnapshot dataSnapshot) {
                // Do something with data
            }
        }, new Action1<Throwable>() {
            @Override
            public void call(Throwable throwable) {
                // NoSuchElementException is thrown when there are no data exist
            }
        });

Kotlin:

val ref: DatabaseReference = ...

ref.data()
        .subscribe({
            // Do something with data
        }) {
            // NoSuchElementException is thrown when there are no data exist
        }

RxJava 2.x

Java:

DatabaseReference ref = ...;

RxFirebaseDatabase.data(ref)
        .subscribe(new Consumer<DataSnapshot>() {
            @Override
            public void accept(DataSnapshot dataSnapshot) {
                // Do something with data
            }
        }, new Consumer<Throwable>() {
            @Override
            public void accept(Throwable throwable) {
                // NoSuchElementException is thrown when there are no data exist
            }
        });

Kotlin:

val ref: DatabaseReference = ...

ref.data()
        .subscribe({
            // Do something with data
        }) {
            // NoSuchElementException is thrown when there are no data exist
        }