Reputation: 39
I have multiple views and want to make a change in Firestore database in every different views when button is tapped.
In firstView
, I have set my data to Firestore and want to update them in the second view when button is tapped.
I noticed that I can not call Firestore in every different view.
As I'm a beginner, how can I implement data updates in different views?
import SwiftUI
import Firebase
struct firstView: View {
var body: some View {
VStack {
Text("Greetings!")
Button(action: {
self.writeDatabase()
}) {
Text("Next")
}
}
}
func writeDatabase() {
let firestoreDatabase = Firestore.firestore()
let firestorePost = [
"PostedBy": Auth.auth().currentUser!.email!,
"date": FieldValue.serverTimestamp(),
"CityName": "",
"DistrictName": ""] as [String : Any]
firestoreDatabase
.collection("Posts")
.document("Dc")
.setData(firestorePost, merge: true) { error in
if error != nil {
print("error")
}
}
}
}
My second view is as follows:
import SwiftUI
import Firebase
struct secondView: View {
var body: some View {
NavigationView {
VStack {
Text("Tap to update...")
NavigationLink(destination: good()) {
Text("Next")
}
.onAppear {
self.update()
}
}
}
}
func update() {
let firestoreDatabase = Firestore.firestore()
firestoreDatabase
.collection("Posts")
.document("Dc")
.updateData(
[
"CityName" : "İstanbul",
"DistrictName": "Beşiktaş"
]
) { (error) in
if error != nil{
print("Error")
}
else {
print("succesfully updated")
}
}
}
}
}
Upvotes: 2
Views: 2092
Reputation: 7254
A couple of notes:
FirstView
and SecondView
firestorePost
) as a dictionary, you should consider implementing a data object using a struct
that implements the Codable
protocol:struct Post: Codable {
var postedBy: String
var cityName: String
var districtName: String
}
struct
much easier: private func addPost(_ post: Post) {
do {
let _ = try db.collection("posts").addDocument(from: post)
}
catch {
print(error)
}
}
private func updatePost(_ post: Post) {
if let documentId = post.id {
do {
try db.collection("posts").document(documentId).setData(from: post)
}
catch {
print(error)
}
}
}
Codable
):class PostsViewModel: ObservableObject {
@Published var posts = [Post]()
private var db = Firestore.firestore()
private var listenerRegistration: ListenerRegistration?
deinit {
unsubscribe()
}
func unsubscribe() {
if listenerRegistration != nil {
listenerRegistration?.remove()
listenerRegistration = nil
}
}
func subscribe() {
if listenerRegistration == nil {
listenerRegistration = db.collection("posts").addSnapshotListener { (querySnapshot, error) in
guard let documents = querySnapshot?.documents else {
print("No documents")
return
}
self.posts = documents.compactMap { queryDocumentSnapshot in
try? queryDocumentSnapshot.data(as: Post.self)
}
}
}
}
}
@StateObject var viewModel = PostsViewModel()
Check out these articles, which provide more background on how to use SwiftUI with Cloud Firestore:
Upvotes: 4