feat(backup): add uploadBackupSnapshot and deleteBackupSnapshot to FirebaseStorageDataSource
This commit is contained in:
parent
909d261b6c
commit
230e7f6201
|
|
@ -68,6 +68,37 @@ class FirebaseStorageDataSource @Inject constructor(
|
||||||
.addOnFailureListener { cont.resumeWithException(it) }
|
.addOnFailureListener { cont.resumeWithException(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uploads an already-encrypted conversation-backup snapshot under the uploader's OWN path and
|
||||||
|
* returns the tokenized download URL (recorded in the couple-gated backup manifest so the partner
|
||||||
|
* can fetch it). The bytes are couple-key ciphertext, so Storage holds nothing readable. Living
|
||||||
|
* under users/{uid}/ means the existing account-delete cleanup covers backups too.
|
||||||
|
*/
|
||||||
|
suspend fun uploadBackupSnapshot(uid: String, snapshotId: String, encryptedBytes: ByteArray): String =
|
||||||
|
suspendCancellableCoroutine { cont ->
|
||||||
|
if (!isOnline()) {
|
||||||
|
cont.resumeWithException(IOException("No internet connection"))
|
||||||
|
return@suspendCancellableCoroutine
|
||||||
|
}
|
||||||
|
val ref = storage.reference.child("users/$uid/backups/$snapshotId")
|
||||||
|
val metadata = StorageMetadata.Builder()
|
||||||
|
.setContentType("application/octet-stream")
|
||||||
|
.build()
|
||||||
|
ref.putBytes(encryptedBytes, metadata)
|
||||||
|
.continueWithTask { ref.downloadUrl }
|
||||||
|
.addOnSuccessListener { cont.resume(it.toString()) }
|
||||||
|
.addOnFailureListener { cont.resumeWithException(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Best-effort delete of a previously-uploaded backup snapshot (post-compaction cleanup; succeeds
|
||||||
|
* only for the uploader's own path, so a cross-partner stale blob is left for that owner/cleanup). */
|
||||||
|
suspend fun deleteBackupSnapshot(uid: String, snapshotId: String): Unit =
|
||||||
|
suspendCancellableCoroutine { cont ->
|
||||||
|
storage.reference.child("users/$uid/backups/$snapshotId").delete()
|
||||||
|
.addOnSuccessListener { cont.resume(Unit) }
|
||||||
|
.addOnFailureListener { cont.resume(Unit) } // best-effort; a leftover blob is harmless ciphertext
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Downloads the raw (still-encrypted) bytes for a media message over HTTP using the tokenized
|
* Downloads the raw (still-encrypted) bytes for a media message over HTTP using the tokenized
|
||||||
* download URL, so the partner can read the author's object (the URL token authorizes it,
|
* download URL, so the partner can read the author's object (the URL token authorizes it,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue