Ad

Android Repository Pattern For Firestore

To have a better separation of concerns I'd like to implement a repository which handles all the firestore interaction.

Currently, my code looks like this:

UserRepository:

public class UserRepository {

    private static final String TAG = "UserRepository";

    private FirebaseFirestore db = FirebaseFirestore.getInstance();
    private CollectionReference usersRef = db.collection("users");

    public Task<DocumentSnapshot> get(String email) {
        DocumentReference docRef = usersRef.document(email); // Users are referenced by email
        Log.d(TAG, "Checking DocumentReference exists for: " + email);
        return docRef.get();
    }
}

MainActivity

                final UserRepository userRepository = new UserRepository();

                userRepository.get(currentUser.getEmail()).addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
                    @Override
                    public void onSuccess(DocumentSnapshot documentSnapshot) {
                        Log.d(TAG, "DocumentSnapshot got");
                        // Do something with user
                    }
                }).addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                        Log.d(TAG, "Could not get DocumentReference", e);
                    }
                });

User is a POJO

What I would like to achieve is a Repository which instead of Task returns Task somewhat like this:

public Task<User> get(String email) {
    DocumentReference docRef = usersRef.document(email);
    /* Convert and return task? */
}

Which then could be used like usual, attaching a listener in the MainActivity. I'm afraid I am somewhat lacking skill in concurrency but I feel like this should be possible without having to synchronize. Could you give me a hint on how to achieve this?

Thanks in advance!

Ad

Answer

Actually the solution was pretty simple, using a Continuation. I was not sure if task-chaining was what I was actually looking for but it seems like a good solution. The get method now looks like this:

public Task<User> get(String email) {
    DocumentReference docRef = getDocumentReference(email);

    return docRef.get().continueWith(new Continuation<DocumentSnapshot, User>() {
        @Override
        public User then(@NonNull Task<DocumentSnapshot> task) throws Exception {
            return task.getResult().toObject(User.class);
        }
    });
}

Edit: Per request I created a gist containing my implementation: Firestore Repository Gist

Ad
source: stackoverflow.com
Ad