Created
April 1, 2022 08:57
-
-
Save eddieberklee/7474ac22426274b314e40d0cdb401b69 to your computer and use it in GitHub Desktop.
HabitDay Firestore Model
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
class HabitDayFS { | |
lateinit var id: String | |
lateinit var habitId: String | |
@get:PropertyName("isCompleted") | |
@set:PropertyName("isCompleted") | |
var isCompleted: Boolean = false | |
var noteText: String = "" | |
lateinit var yearMonthDay: String | |
constructor() {} | |
constructor(habitId: String, ymd: YearMonthDay, isCompleted: Boolean) { | |
this.habitId = habitId | |
this.yearMonthDay = ymd | |
this.id = getKey(habitId, ymd) | |
this.isCompleted = isCompleted | |
} | |
fun deleteOnFirebase() { | |
getHabitDayReference(habitId, id) | |
.delete() | |
.addOnCompleteListener { | |
if (FirebaseEtil.handleFirestoreErrorTaskVoid( | |
it, | |
"Could not successfully delete the habit day") | |
) { | |
return@addOnCompleteListener | |
} | |
Timber.d("Successfully deleted habitId: $habitId") | |
} | |
} | |
fun updateFirestore() { | |
getCollectionReference() | |
.document(id) | |
.set(this) | |
.addOnCompleteListener { | |
if (FirebaseEtil.handleFirestoreErrorTaskVoid(it, "Failed to update habit day $id")) { | |
return@addOnCompleteListener | |
} | |
Timber.d("Successfully updated habit day $id") | |
} | |
} | |
companion object { | |
const val HABIT_DAY_COLLECTION = "habitDay" | |
const val FIELD_ID = "id" // year month day | |
const val FIELD_IS_COMPLETED = "isCompleted" | |
const val FIELD_NOTE_TEXT = "noteText" | |
const val FIELD_HABIT_ID = "habitId" | |
fun getCollectionReference(): CollectionReference { | |
return FirebaseFirestore | |
.getInstance() | |
.collection(HABIT_DAY_COLLECTION) | |
} | |
private fun getKey(habitId: String, ymd: YearMonthDay): String { | |
return "${AuthUtil.getUUID()}_${habitId}_$ymd" | |
} | |
fun fetchHabitDayOnce( | |
habitDayId: String, | |
onFetchCallback: ((habitDay: HabitDayFS) -> Unit)? = null | |
) { | |
getCollectionReference() | |
.document(habitDayId) | |
.get() | |
.addOnCompleteListener { | |
if (FirebaseEtil.handleFirestoreErrorDocumentSnapshot( | |
it, | |
"Failed to fetch habit day $habitDayId") | |
) { | |
return@addOnCompleteListener | |
} | |
Timber.d("Successfully fetched habit day $habitDayId") | |
val habitDay = it.result.toObject(HabitDayFS::class.java)!! | |
onFetchCallback?.invoke(habitDay) | |
} | |
} | |
@JvmStatic | |
@Exclude | |
fun updateIsCompletedInFirestore( | |
userEmail: String, | |
habitId: String, | |
ymd: String, | |
isCompleted: Boolean | |
) { | |
getHabitDayReference(habitId, ymd) | |
.update(FIELD_IS_COMPLETED, isCompleted) | |
.addOnSuccessListener { aVoid: Void? -> | |
Timber.d( | |
"Updated habitId: %s habitDayId: %s isCompleted: %s ymd $ymd", | |
habitId, | |
ymd, | |
isCompleted | |
) | |
} | |
.addOnFailureListener { e: Exception -> | |
Timber.e( | |
"Failed to update habit as completed userEmail: $userEmail yearMonthDay: $ymd habitId: $habitId") | |
CrashUtil.logAndShowToast( | |
"Failed to update habit as completed: ${e.message}" | |
) | |
} | |
} | |
@JvmStatic | |
@Exclude | |
fun getHabitDayReference( | |
habitId: String, | |
ymd: YearMonthDay | |
): DocumentReference { | |
return getCollectionReference() | |
.document(getKey(habitId, ymd)) | |
} | |
@JvmStatic | |
@Exclude | |
fun createNewAsCompletedFirestore( | |
habitId: String, | |
ymd: String | |
) { | |
val newHabitDay = HabitDayFS(habitId, ymd, isCompleted = true) | |
getCollectionReference() | |
.document(getKey(habitId, ymd)) | |
.set(newHabitDay) | |
.addOnCompleteListener { | |
if (FirebaseEtil.handleFirestoreErrorTaskVoid( | |
it, | |
"Failed to create new habit day ymd=$ymd id=${newHabitDay.id} habitId=$habitId")) { | |
return@addOnCompleteListener | |
} | |
Timber.d("Successfully created new habit day ymd=$ymd id=${newHabitDay.id} habitId=$habitId") | |
} | |
} | |
@JvmStatic | |
fun migrateData(uuid: String, email: String, onCompleteRunnable: Runnable) { | |
// querying each habit for its id | |
HabitFS.habitCollection | |
.get() | |
.addOnCompleteListener { task1: Task<QuerySnapshot> -> | |
if (CrashUtil.didHandleFirestoreException(task1.exception)) { | |
return@addOnCompleteListener | |
} | |
if (task1.isSuccessful) { | |
for (document in task1.result) { | |
val habit = document.toObject(HabitFS::class.java) | |
// todo: using habit id to get all habit days | |
getCollectionReference() | |
.get() | |
.addOnCompleteListener { task2: Task<QuerySnapshot> -> | |
if (CrashUtil.didHandleFirestoreException(task2.exception)) { | |
return@addOnCompleteListener | |
} | |
if (task2.isSuccessful) { | |
for (document1 in task2.result) { | |
val habitDay = document1.toObject(HabitDayFS::class.java) | |
// copying over all habit days | |
// todo: doesn't habit id need to b e used | |
getCollectionReference() | |
.add(habitDay) | |
.addOnCompleteListener { task3: Task<DocumentReference?> -> | |
if (CrashUtil.didHandleFirestoreException(task3.exception)) { | |
return@addOnCompleteListener | |
} | |
if (task3.isSuccessful) { | |
Timber.d( | |
"Successfully copied over habit day %s from %s to %s", | |
habitDay.id, | |
uuid, | |
) | |
onCompleteRunnable.run() | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
fun deleteAllHabitDays(habitId: String) { | |
getCollectionReference() | |
.get() | |
.addOnCompleteListener { | |
if (it.exception != null) { | |
CrashEtil.logAndShowToast(it.exception?.message) | |
return@addOnCompleteListener | |
} | |
for (documentSnapshot in it.result.documents) { | |
val habitDay = documentSnapshot.toObject(HabitDayFS::class.java) | |
// todo: is there a better way to delete documents from a collection? | |
habitDay?.deleteOnFirebase() | |
} | |
} | |
} | |
fun queryContinuously( | |
habitId: String, | |
callback: (List<HabitDayFS>) -> Unit | |
): ListenerRegistration { | |
return getCollectionReference() | |
.whereEqualTo(FIELD_HABIT_ID, habitId) | |
.addSnapshotListener { value, error -> | |
if (error != null) { | |
Timber.e("Failed to query habit days with habit id $habitId, message=${error.message}") | |
return@addSnapshotListener | |
} | |
Timber.d("Successful snapshot of new habit days (${value?.size()})") | |
val habitDays = value?.toObjects(HabitDayFS::class.java) | |
if (habitDays == null) { | |
Timber.d("Habit days is null") | |
} else { | |
callback.invoke(habitDays) | |
} | |
} | |
} | |
fun updateFieldsFirestore(habitDayId: String, updateMap: Map<String, Any>) { | |
getCollectionReference() | |
.document(habitDayId) | |
.update(updateMap) | |
.addOnCompleteListener { | |
if (FirebaseEtil.handleFirestoreErrorTaskVoid( | |
it, | |
"Failed to update fields for habit day id $habitDayId")) { | |
return@addOnCompleteListener | |
} | |
Timber.d("Successfully updated fields for habit day id $habitDayId") | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment