Ive been looking all over for documentation on using the Realtime Database with SwiftUI but all I find is information on using Firestore or old information with UIKit. Is there any info on how to just read from a database with a basic example?
3 Answers
In general, in SwiftUI, it's helpful to put networking/asynchronous code like Firebase into an ObservableObject that the View has access to. Then, you can use a trigger like onAppear to run your Firebase functions. Then, when a @Published property on your ObservableObject changes, your view will automatically re-render.
For example:
class FirebaseManager : ObservableObject {
@Published var result : String?
func makeFirebaseCall() {
//make your Firebase data call here -- plenty of examples exist on how to do this, which is not SwiftUI or UIKit specific. When the Firebase call returns, set the returned value to your @Published property.
self.result = //the result of my firebase call
}
}
}
struct ContentView : View {
@StateObject private var firebaseManager = FirebaseManager()
var body : some View {
VStack {
Text("Hello, world")
if let result = firebaseManager.result {
Text(result)
}
}.onAppear {
firebaseManager.makeFirebaseCall()
}
}
}
Comments
The SwiftUI is a fast way of generating an app, but when it comes to addressing user data, there is no prebuilt solution as each project is unique and different. Instead, you would introduce code on pages that loads data respective for that apps page needs.
An example from Firebase which gets data once:
self.ref.child("users/\(user.uid)/username").getData { (error, snapshot) in
if let error = error {
print("Error getting data \(error)")
}
else if snapshot.exists() {
print("Got data \(snapshot.value!)")
}
else {
print("No data available")
}
}
You can find iOS documentation here: https://firebase.google.com/docs/database/ios/read-and-write
And here is a quick guide on how to make an app for SwiftUI and Firebase Realtime: https://medium.com/flawless-app-stories/how-to-build-a-firebase-app-with-swiftui-5919d2d8a396
Comments
func getMessages(for chatId: String, completion: @escaping ([MessagesChat]?, Error?) -> Void) {
ref.child("Messages").child(chatId).child("user1").observe(.value) { snapshot in
if !snapshot.exists() {
print("No messages found at path:")
return
}
guard let value = snapshot.value as? [String: Any] else {
print("Invalid data format at path:")
return
}
print("Fetched data: \(value)")
var messages: [MessagesChat] = []
for (_, messageData) in value {
if let messageDict = messageData as? [String: Any] {
// Manually map the dictionary to ChatModel
let message = MessagesChat(
id: messageDict["id"] as? String,
isread: messageDict["isread"] as? Bool,
msg: messageDict["messages"] as? String,
messages.append(message)
}
}
completion(messages, nil)
}
}
let chatId = "\(viewModal.currentUserUID)\(user.id ?? "")"
viewModal.getMessages(for: chatId) { fetchedMessages, error in
if let error = error {
print("Error fetching messages: \(error)")
} else if let fetchedMessages = fetchedMessages {
messages = fetchedMessages
}
}