Giter Site home page Giter Site logo

rx2firebase's Introduction

Rx2Firebase

Rxjava 2.0 wrapper on Google's Android Firebase library.

This repository started as a personal usage of Nick Moskalenko RxFirebase library. You can check his work here.

Download

Gradle:
dependencies {
  compile 'com.github.frangsierra:rx2firebase:1.1.3'
}
allprojects {
		repositories {
			...
			maven { url "https://jitpack.io" }
		}
	}

RxJava and RxJava 2.0

One of the differences between RxJava and RxJava 2 is that RxJava 2 no longer accepts null values. Throwing a NullPointerException immediately. For this reason some of the methods of the library as been redesigned to return a Completable instead of a Observable<Void>. For example:

RxFirebase

@NonNull
public static Observable<Void> updateEmail(@NonNull final FirebaseUser firebaseUser, @NonNull final String email) {
        return Observable.create(new Observable.OnSubscribe<Void>() {
            @Override
            public void call(final Subscriber<? super Void> subscriber) {
                RxHandler.assignOnTask(subscriber, firebaseUser.updateEmail(email));
            }
        });
}

Rx2Firebase

@NonNull
public static Completable updateEmail(@NonNull final FirebaseUser firebaseUser, @NonNull final String email) {
        return Completable.create(new CompletableOnSubscribe() {
            @Override
            public void subscribe(CompletableEmitter emitter) throws Exception {
                RxCompletableHandler.assignOnTask(emitter, firebaseUser.updateEmail(email));
            }
        });
}

RxCompletableHandler manages the CompletableEmitters in the same way that RxHandler manages the Subscriber. You can check all the differences between RxJava and RxJava 2.0 in the next Link

Usage

Library provides set of static methods of classes:

  • RxFirebaseAuth
  • RxFirebaseUser
  • RxFirebaseDatabase
  • RxFirebaseStorage

It also provides a custom implementation of FirebaseRecyclerAdapter:

  • RxFirebaseRecyclerAdapter

Authentication:

Sign in with email and password:

    RxFirebaseAuth.signInWithEmailAndPassword(auth, email, password)
                .map(authResult -> authResult.getUser() != null)
                .take(1)
                .subscribe(logged -> {
                    Log.i("Rxfirebase2", "User logged " + logged);
                });

Database:

You can observe values providing the Class of expected data like:

    RxFirebaseDatabase.observeSingleValueEvent(getPostsRef().child("posts"), Post.class)
                .subscribe(post -> {
           //Do something with yourpost 
        });

or providing your own mapper between DataSnapshot and your data type:

    RxFirebaseDatabase.observeSingleValueEvent(getPostsRef().child("posts"),
                dataSnapshot -> {
                    // do your own mapping here
                    return new Author();
                })
                .subscribe(author -> {
                    // process author value
                });

There are some pre-defined mappers to make things easier:

Observing list values
    RxFirebaseDatabase.observeSingleValueEvent(getPostsRef().child("posts"), DataSnapshotMapper.listOf(PostComment.class))
                .subscribe(blogPost -> {
                    // process postcomment list item
                });
Observing map values
     RxFirebaseDatabase.observeSingleValueEvent(getPostsRef().child("posts"), DataSnapshotMapper.mapOf(PostComment.class))
                .subscribe(PostCommentAsMapItem -> {
                    // process blogPost as key-value pair
                });

Storage:

Download file from Firebase storage

    RxFirebaseStorage.getFile(getStorageRef(), targetFile)
                .subscribe(taskSnapshot -> {
                    Log.i("RxFirebaseSample", "transferred: " + snapshot.getBytesTransferred() + " bytes");
                }, throwable -> {
                    Log.e("RxFirebaseSample", throwable.toString());
            });

or download file as bytes array

    RxFirebaseStorage.getBytes(getStorageRef(), 1024 * 100)
                .subscribe(bytes -> {
                    Log.i("RxFirebaseSample", "downloaded: " + new String(bytes));
                }, throwable -> {
                    Log.e("RxFirebaseSample", throwable.toString());
            });

RxFirebaseQuery

RxFirebaseQuery is a builder class used to work together with methods from RxFirebaseDatabase that allow you to retrieve data from multiple databaseReferences. Doing this allow you to build and create dynamic queries to retrieve database objects from references retrieved from different tables easily. At the moment RxFirebaseQuery just allow the user to create the queries and retrieve the data. Filters should be done with the DatabaseReference items that you pass to the constructor. In other hand for update and delete data you should use Firebase method updateChildren()

	DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
		      DatabaseReference from = reference.child("tweets");
		      Query where = reference.child("users").child(userId).child("feedReferences");
		      RxFirebaseQuery.getInstance()
			    .filterByRefs(from, where)
			    .asList()
			    .subscribe(dataSnapshots -> {
			       Log.i("RxFirebase", "Retrieved a total of " + dataSnapshots.size() + " tweets");
			       for (DataSnapshot dataSnapshot : dataSnapshots) {
				  Tweet tweet = dataSnapshot.getValue(Tweet.class);
				  Log.i("RxFirebase", "New tweet for user feed: " + tweet.getDescription());
			       }
			    });

RxFirebaseRecyclerAdapter:

RxFirebaseRecyclerAdapter was created looking for a way to manage the RxFirebaseChildEvent<DataSnapshot> items recieved with the observeChildEvent method. It is an abstract class based on FirebaseRecyclerAdapter but modifying the query and firebase call dependency. Doing this, now it only recieve a RxFirebaseRecyclerAdapter and using the method manageChildItemit will manage the ChildEvent doing the right task based on the EventType of the item:

For example:

Posts are emited to our disposable:
   RxFirebaseDatabase.observeChildEvent(getPostsRefFromGroup(groupId))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(post -> {
                    getView().managePost(post);
                    getView().showLoadingProgressBar(false);
                }, throwable -> {
                    getView().showLoadingProgressBar(false);
                    getView().showReloadLayout(true);
                }));    
We call manageChildItem(item) in our Custom adapter which extends RxFirebaseRecyclerAdapter:
 public void managePost(RxFirebaseChildEvent<DataSnapshot> post) {
        if(postRecyclerView.getVisibility() != View.VISIBLE) {
            postRecyclerView.setVisibility(View.VISIBLE);
        }
        if (adapter == null){
            adapter = new PostAdapter(this, this);
            postRecyclerView.setAdapter(adapter);
        }
        adapter.manageChildItem(post);
    }
Custom adapter example:
public class PostAdapter extends RxFirebaseRecyclerAdapter<PostViewHolder, Post> {
    private static final String TAG = "PostAdapter";

    public PostAdapter() {
        super(Post.class);
    }

    @Override
    public PostViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        //Initialize your Holder
    }

    @Override
    public void onBindViewHolder(PostViewHolder holder, int position) {
        Post post = getItems().get(position);
       //bind your post
    }

    @Override
    protected void itemAdded(Post item, String key, int position) {
        //Add the refs if you need them later
        item.setRef(key);
        Log.d(TAG, "Added a new item to the adapter.");
    }

    @Override
    protected void itemChanged(Post oldItem, Post newItem, String key, int position) {
        //Add the refs if you need them later
        newItem.setRef(key);
        Log.d(TAG, "Changed an item.");
    }

    @Override
    protected void itemRemoved(Post item, String key, int position) {
        Log.d(TAG, "Removed an item.");
    }

    @Override
    protected void itemMoved(Post item, String key, int oldPosition, int newPosition) {
        Log.d(TAG, "Moved an item.");
    }

}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.