-
-
Save CarlosACepeda/a7e2d94ce42c27d4c540c7a8480bb16d to your computer and use it in GitHub Desktop.
Basic implementation of a repository pattern for Firebase Firestore
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package ch.jojoni.jamplan.model.repository; | |
import android.support.annotation.NonNull; | |
import android.util.Log; | |
import com.google.android.gms.tasks.Continuation; | |
import com.google.android.gms.tasks.OnFailureListener; | |
import com.google.android.gms.tasks.Task; | |
import com.google.firebase.firestore.CollectionReference; | |
import com.google.firebase.firestore.DocumentReference; | |
import com.google.firebase.firestore.DocumentSnapshot; | |
import com.google.firebase.firestore.FirebaseFirestore; | |
import ch.jojoni.jamplan.model.Identifiable; | |
/** | |
* Manages data access for Firebase | |
*/ | |
public class FirestoreRepository<TEntity extends Identifiable<String>> implements Repository<TEntity, String> { | |
private static final String TAG = "FirestoreRepository"; | |
private final Class<TEntity> entityClass; | |
private final CollectionReference collectionReference; | |
private final String collectionName; | |
/** | |
* Initializes the repository storing the data in the given collection. Should be from {@link FirestoreCollections}. | |
*/ | |
public FirestoreRepository(Class<TEntity> entityClass, String collectionName) { | |
this.collectionName = collectionName; | |
this.entityClass = entityClass; | |
FirebaseFirestore db = FirebaseFirestore.getInstance(); | |
this.collectionReference = db.collection(this.collectionName); | |
} | |
@Override | |
public Task<Boolean> exists(final String documentName) { | |
DocumentReference documentReference = collectionReference.document(documentName); | |
Log.i(TAG, "Checking existence of '" + documentName + "' in '" + collectionName + "'."); | |
return documentReference.get().continueWith(new Continuation<DocumentSnapshot, Boolean>() { | |
@Override | |
public Boolean then(@NonNull Task<DocumentSnapshot> task) { | |
Log.d(TAG,"Checking if '" + documentName + "' exists in '" + collectionName +"'."); | |
return task.getResult().exists(); | |
} | |
}); | |
} | |
@Override | |
public Task<TEntity> get(String id) { | |
final String documentName = id; | |
DocumentReference documentReference = collectionReference.document(documentName); | |
Log.i(TAG, "Getting '" + documentName + "' in '" + collectionName + "'."); | |
return documentReference.get().continueWith(new Continuation<DocumentSnapshot, TEntity>() { | |
@Override | |
public TEntity then(@NonNull Task<DocumentSnapshot> task) throws Exception { | |
DocumentSnapshot documentSnapshot = task.getResult(); | |
if (documentSnapshot.exists()) { | |
return documentSnapshot.toObject(entityClass); | |
} else { | |
Log.d(TAG, "Document '" + documentName + "' does not exist in '" + collectionName + "'."); | |
return entityClass.newInstance(); | |
} | |
} | |
}); | |
} | |
@Override | |
public Task<Void> create(TEntity entity) { | |
final String documentName = entity.getEntityKey(); | |
DocumentReference documentReference = collectionReference.document(documentName); | |
Log.i(TAG, "Creating '" + documentName + "' in '" + collectionName + "'."); | |
return documentReference.set(entity).addOnFailureListener(new OnFailureListener() { | |
@Override | |
public void onFailure(@NonNull Exception e) { | |
Log.d(TAG, "There was an error creating '" + documentName + "' in '" + collectionName + "'!", e); | |
} | |
}); | |
} | |
@Override | |
public Task<Void> update(TEntity entity) { | |
final String documentName = entity.getEntityKey(); | |
DocumentReference documentReference = collectionReference.document(documentName); | |
Log.i(TAG, "Updating '" + documentName + "' in '" + collectionName + "'."); | |
return documentReference.set(entity).addOnFailureListener(new OnFailureListener() { | |
@Override | |
public void onFailure(@NonNull Exception e) { | |
Log.d(TAG, "There was an error updating '" + documentName + "' in '" + collectionName + "'.", e); | |
} | |
}); | |
} | |
@Override | |
public Task<Void> delete(final String documentName) { | |
DocumentReference documentReference = collectionReference.document(documentName); | |
Log.i(TAG, "Deleting '" + documentName + "' in '" + collectionName + "'."); | |
return documentReference.delete().addOnFailureListener(new OnFailureListener() { | |
@Override | |
public void onFailure(@NonNull Exception e) { | |
Log.d(TAG, "There was an error deleting '" + documentName + "' in '" + collectionName + "'.", e); | |
} | |
}); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package ch.jojoni.jamplan.model; | |
import com.google.firebase.firestore.Exclude; | |
/** | |
* Represents an object that can be uniquely identified among other objects of the same type | |
* by using an UID. | |
* | |
* @param <TKey> type of the unique key (UID) this object is uniquely identified by. The type needs | |
* a correct implementation of its equals() method or the behaviour of code using this | |
* interface will be undefined. | |
*/ | |
public interface Identifiable<TKey> { | |
@Exclude | |
TKey getEntityKey(); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package ch.jojoni.jamplan.model.repository; | |
import com.google.android.gms.tasks.Task; | |
import ch.jojoni.jamplan.model.Identifiable; | |
/** | |
* Manages data access for POJOs that are uniquely identifiable by a key, such as POJOs implementing {@link Identifiable}. | |
*/ | |
public interface Repository<TEntity extends Identifiable<TKey>, TKey> { | |
/** | |
* Checks the repository for a given id and returns a boolean representing its existence. | |
* @param id the unique id of an entity. | |
* @return A {@link Task} for a boolean which is 'true' if the entity for the given id exists, 'false' otherwise. | |
*/ | |
Task<Boolean> exists(TKey id); | |
/** | |
* Queries the repository for an uniquely identified entity and returns it. If the entity does | |
* not exist in the repository, a new instance is returned. | |
* @param id the unique id of an entity. | |
* @return A {@link Task} for an entity implementing {@link Identifiable}. | |
*/ | |
Task<TEntity> get(TKey id); | |
/** | |
* Stores an entity in the repository so it is accessible via its unique id. | |
* @param entity the entity implementing {@link Identifiable} to be stored. | |
* @return An {@link Task} to be notified of failures. | |
*/ | |
Task<Void> create(TEntity entity); | |
/** | |
* Updates an entity in the repository | |
* @param entity the new entity to be stored. | |
* @return A {@link Task} to be notified of failures. | |
*/ | |
Task<Void> update(TEntity entity); | |
/** | |
* Deletes an entity from the repository. | |
* @param id uniquely identifying the entity. | |
* @return A {@link Task} to be notified of failures. | |
*/ | |
Task<Void> delete(TKey id); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment