*Featuring: SnackAttack - Realtime Snack Voting App πͺπ©π
Welcome, fearless developer! π§ββοΈβ¨ Today we dive into the exciting world of Firebase Firestore β Google's magic cloud database for realtime data sync!
And we won't just talk β we'll build an epic app: SnackAttack πΏ β a real-time snack voting app where users battle it out over which snack rules supreme! π₯π
π What You'll Learn
- What is Firebase Firestore?
- Setting up Firebase in your iOS project
- Creating, updating, and listening to realtime data
- Building a voting app with SwiftUI + Firestore
π₯ What Is Firestore?
- NoSQL cloud database by Google π
- Realtime updates β changes show up instantly without refresh β‘
- Offline support β keeps working even when you lose signal! πΆ
- Cross-platform β mobile, web, and server ready π
Perfect for any app that needs live data flying around! π«
π Project Setup
- Create a new Xcode project (App template).
- Install Firebase SDK via Swift Package Manager:
- URL:
https://github.com/firebase/firebase-ios-sdk
- URL:
- Set up a Firebase project:
- Go to Firebase Console
- Create a new project.
- Add an iOS app (get your GoogleService-Info.plist).
- Download and drag
GoogleService-Info.plist
into Xcode.
- Configure Firebase in your app:
import Firebase
@main
struct SnackAttackApp: App {
init() {
FirebaseApp.configure()
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
π© Designing the SnackAttack Database
In Firestore, we'll have a collection called snacks
:
Field | Type | Description |
---|---|---|
name | String | Name of the snack |
votes | Int | Number of votes |
Each snack is a document. Simple. Fast. Delicious. π©
β¨ SwiftUI + Firestore Snack Voting App
import SwiftUI
import FirebaseFirestore
import FirebaseFirestoreSwift
struct Snack: Identifiable, Codable {
@DocumentID var id: String?
var name: String
var votes: Int
}
class SnackViewModel: ObservableObject {
@Published var snacks = [Snack]()
private var db = Firestore.firestore()
init() {
fetchData()
}
func fetchData() {
db.collection("snacks").order(by: "votes", descending: true)
.addSnapshotListener { (querySnapshot, error) in
guard let documents = querySnapshot?.documents else {
print("π± No documents: \(error?.localizedDescription ?? "unknown error")")
return
}
self.snacks = documents.compactMap { document -> Snack? in
try? document.data(as: Snack.self)
}
}
}
func addSnack(name: String) {
do {
_ = try db.collection("snacks").addDocument(from: Snack(name: name, votes: 0))
} catch {
print("π± Error adding snack: \(error.localizedDescription)")
}
}
func vote(for snack: Snack) {
if let id = snack.id {
db.collection("snacks").document(id).updateData([
"votes": snack.votes + 1
])
}
}
}
struct ContentView: View {
@StateObject private var viewModel = SnackViewModel()
@State private var newSnackName = ""
var body: some View {
NavigationView {
VStack {
HStack {
TextField("New Snack", text: $newSnackName)
.textFieldStyle(RoundedBorderTextFieldStyle())
Button(action: {
viewModel.addSnack(name: newSnackName)
newSnackName = ""
}) {
Text("Add πͺ")
.padding(.horizontal)
}
}
.padding()
List(viewModel.snacks) { snack in
HStack {
Text(snack.name)
Spacer()
Text("\(snack.votes) π΄")
Button(action: {
viewModel.vote(for: snack)
}) {
Text("Vote β
")
}
}
}
}
.navigationTitle("SnackAttack π")
}
}
}
β‘ How Realtime Sync Works
- Add a snack β‘οΈ Instantly shows for everyone.
- Vote for a snack β‘οΈ Instant update across all devices.
- New users see live leaderboard without manual refreshes.
Magic? Almost. π
π§ Pro Tips for Firestore
- Security Rules: Lock down your database! Donβt leave it open to everyone. π
- Indexes: Firestore automatically creates indexes but optimize when needed for performance.
- Batch Writes: Bundle multiple updates in one request.
- Offline Support: Firestore caches data β amazing for mobile!
π― Stretch Challenges for SnackAttack
- Add snack categories (Sweet π©, Savory π, Healthy π₯).
- Show snack pictures with
Firebase Storage
. - Sort by most recently added snacks.
- Add user authentication to track who voted.
Congratulations, Realtime Rockstar! π
You built a cloud-connected, real-time updating app that syncs delicious snack battles across the globe. ππ
Keep coding, keep shipping, and remember: the snack must go on! ππͺπ©π
Let me know if you want a bonus follow-up tutorial where we add user login with Firebase Authentication so voters can only vote once! π―ποΈ
Top comments (0)