I am creating a information reader ios utility that reads articles from Firestore – only for me in the meanwhile. The app wants to trace which articles I’ve learn, however I am involved about exceeding the every day free quota restrict of 20,000 write operations. At present, I am writing a couple of thousand articles per day to the database. (I’m not studying all of them, simply skimming the headlines principally). Afterward possibly if there are extra customers saving on write operations shall be even a better concern.
- What’s essentially the most environment friendly solution to observe learn standing with out extreme write operations?
- Ought to I create a separate assortment for learn standing?
- Are there higher approaches to deal with this use case whereas staying inside free quota limits?
Present Setup
struct Article {
let id: String
let title: String
let content material: String
let isRead: Bool
let timestamp: Date
}
Technical Particulars
- Platform: iOS/SwiftUI
- Database: Firebase Firestore
- Each day write operations: ~1000-3000
- Free tier limits are a priority
What I’ve Tried
I thought of updating the article doc instantly:
func markAsRead(articleId: String) async throws {
let ref = db.assortment("articles").doc(articleId)
attempt await ref.updateData([
"isRead": true,
"readTimestamp": Date()
])
}
- The app wants to trace learn/unread standing per consumer
- Offline assist could be good to have however not required
- Actual-time updates aren’t crucial
Replace: I am contemplating a special method that is perhaps extra environment friendly:
As a substitute of marking particular person articles as learn, I might retailer only a single timestamp representing when the consumer final caught up with their articles:
// Construction in Firestore
customers/{userId}/studying/{deviceId} {
lastReadTimestamp: timestamp
}
// Replace timestamp when consumer reads articles
func updateLastRead(userId: String, deviceId: String) async throws {
let ref = db.assortment("customers").doc(userId)
.assortment("studying").doc(deviceId)
attempt await ref.setData([
"lastReadTimestamp": FieldValue.serverTimestamp()
])
}
// Question unread articles
func getUnreadArticles(userId: String, deviceId: String) async throws -> [Article] {
let readingDoc = attempt await db.assortment("customers")
.doc(userId)
.assortment("studying")
.doc(deviceId)
.getDocument()
let lastRead = readingDoc.knowledge()?["lastReadTimestamp"] as? Timestamp ?? Timestamp(date: Date(timeIntervalSince1970: 0))
let snapshot = attempt await db.assortment("articles")
.whereField("timestamp", isGreaterThan: lastRead)
.getDocuments()
return snapshot.paperwork.map { /* mapping logic */ }
}
Advantages of this method:
Just one write operation per studying session as a substitute of marking every article
Environment friendly querying utilizing timestamp comparability
Can observe learn standing per gadget
Scales effectively with giant numbers of articles
Stays effectively inside free quota limits
Would this be a greater resolution? Are there any drawbacks I ought to contemplate?