Firebase技术咨询:如何将收据Firestore文档ID替换为当前用户UID以实现照片存储与数据关联
Let's work through this step by step to make sure your receipt photos are perfectly tied to Firestore documents using the user's UID as the document ID. Here's how to adjust your code properly:
1. Fix Firestore Document Creation (Use UID as Document ID)
Your current code uses add() which generates an auto-generated ID—we’ll replace that with document(uid).set() to directly use the user’s UID as the document ID. This removes the need to later update the document to set an id field, since the document ID itself is already the UID.
// Modified: New receipt document creation code val currentUser = auth.currentUser ?: return // Guard against unauthenticated users val uid = currentUser.uid db.collection("receipts") .document(uid) .set(data) // Creates/overwrites the document with UID as its ID .addOnSuccessListener { Log.d(SCAN_DEBUG, "DocumentSnapshot created with ID: $uid") } .addOnFailureListener { e -> Log.w(SCAN_DEBUG, "Error creating document", e) }
Key Changes:
- Added a null check for
auth.currentUserto avoid crashes if the user isn’t logged in. - Replaced
add(data)withdocument(uid).set(data)to explicitly set the document ID to the user’s UID. - Removed the extra
update("id", documentReference.id)call—it’s no longer needed since the document ID is already the UID.
2. Verify & Refine Photo Upload & URL Update Logic
Your existing upload code already uses the user’s UID for the storage filename (${uid}.jpg) and updates the matching Firestore document. That’s already aligned with our goal, but let’s add consistency with null checks:
// Modified: Upload receipt photo fun uploadReceiptPhoto(bytes: ByteArray) { val currentUser = auth.currentUser ?: run { Log.d(SCAN_DEBUG, "No authenticated user found") return } val uid = currentUser.uid storage.getReference("receipts") .child("$uid.jpg") .putBytes(bytes) .addOnCompleteListener{ Log.d(SCAN_DEBUG, "COMPLETE UPLOAD PHOTO") } .addOnSuccessListener { getReceiptPhotoDownloadUrl(it.storage) } .addOnFailureListener { Log.d(SCAN_DEBUG, it.message.toString()) } } private fun getReceiptPhotoDownloadUrl(storage: StorageReference) { storage.downloadUrl .addOnSuccessListener { updateReceiptPhoto(it.toString()) } .addOnFailureListener { Log.d(SCAN_DEBUG, it.message.toString()) } } private fun updateReceiptPhoto(url: String) { val currentUser = auth.currentUser ?: run { Log.d(SCAN_DEBUG, "No authenticated user found") return } val uid = currentUser.uid cloud.collection("receipts") .document(uid) .update("image", url) .addOnSuccessListener { Log.d(SCAN_DEBUG, "UPDATE USER PHOTO") } .addOnFailureListener { Log.d(SCAN_DEBUG, it.message.toString()) } }
Key Notes:
- Added null checks for
auth.currentUserin all relevant functions to make the code more robust. - The storage filename (
$uid.jpg) matches the Firestore document ID (uid), so the photo and document are guaranteed to be linked correctly.
3. Important Considerations
- Authentication State: Always confirm the user is authenticated before running these operations—our null checks help prevent unexpected crashes here.
- Document Overwrites: Using
set()will overwrite the document if it already exists. If you want to preserve existing data when updating, useset(data, SetOptions.merge())instead. - Multiple Receipts per User: If a user can have multiple receipts, this one-to-one structure won’t work. Instead, you could create a subcollection under the user’s UID for their receipts, or add a
userIdfield to each receipt document while keeping auto-generated IDs.
内容的提问来源于stack exchange,提问作者MaksChojniak1

