Information on how SwiftUI handles data retrieved from Firestore.

Asked 2 years ago, Updated 2 years ago, 274 views

Question details
I am studying SwiftUI, and I am making a sample program to save the data in Firebase and do it again.
I have a question about how to handle the data extracted from Firebase.

While checking the Firebase HP documentation, I managed to register, save, and retrieve the application, but the data I got was in document units?, so I don't know how to selectively retrieve some data in the document.
What should I do?

I'm sorry for the confusing explanation, but I have added a comment line to the source code to explain the situation in more detail.
(I think it should be written in the official Firebase document, but I have not been able to find it yet because it finally moved after seeing it.
Thank you for your cooperation.


What does the following two descriptions mean when translated into languages?
I want to understand it properly, so it would be very helpful if you could let me know.
Thank you for your cooperation.

1, docRef.getDocument {(document, error) in...} Description (A)
2, document = document (B)

Created code

//Xcode version 12.4
// Swift version 5.3.2
// Cocoapods version 1.10.1 (write pod 'Firebase/Firestore')

import SwiftUI
import Firebase

struct ContentView:View {

    @State private varword1=""
    @State private varword2=""

    @State private var dataDescription=""

    varbody:someView {

        Text ("Firestore Test")
            .padding()

        VStack {
            HSTack {
                Text ("Input 1")
                TextField("Save words to Firestore", text:$word1) // Enter Aio
            }
            HSTack {
                Text ("Input 2" )
                TextField("Save words to Firestore", text:$word2) // Write
            }
        }

        Button(action: {
            let db = Firestore.firestore()
            db.collection("collectionnameX").document("docentnameX").setData([
                "savedata1": word1,
                "savedata2"—word2
            ]) {errin
                iflet err=err{
                    print("Error writing document:\(err)")
                } else{
                    print("Document successfully write!")
                }
            }
        }){
            Text ("Save to Firestore")
                .border (Color.green, width:1)
        }
        Button(action: {
            let db = Firestore.firestore()
            let docRef=db.collection("collectionnameX").document("docmentnameX")
            docRef.getDocument {( document, error) in//...(A)
                iflet document= document, document.exists {//...(B)
                    dataDescription= document.data().map(String.init(describing:))??? "nil"
                    print("Document data:\(dataDescription)")
                } else{
                    print("Document does not exist")
                }
            }
        }){
            Text ("Retrieved from Firesore")
                .border (Color.green, width:1)
        }
        Text ("View Data Retrieved")
        // Below are the details of the questions.
        // In Text("\(dataDescription)" below, click
        // "Document data: ["savedata1": Ayeo, "savedata2": Kakikakeko]US>" appears.
        // What should I do to take out the value of savedata1?
        // I tried writing like dataDescription.savedata1 or dataDescription["savedata1"], but it didn't work.
        Text("\"(dataDescription)")
    }
}

structureContentView_Previews:PreviewProvider{
    static var previews:someView {
        ContentView()
    }
}

swift firebase swiftui

2022-09-30 21:55

1 Answers

You have declared dataDescription in the String type, so you need string manipulation to extract some elements from that state.

The result of data() in the FireStore is an optional dictionary type ([String:Any]?).map(String.init(describing:)) should be taken out of the dictionary state.

let db=Firestore.firestore()
            let docRef=db.collection("collectionnameX").document("docmentnameX")
            docRef.getDocument {( document, error) in
                iflet document= document, document.exists{
                    iflet docDict= document.data(),
                       let savedata1 = docDict ["savedata1" ] as ? String,
                       let savedata2 = docDict ["savedata2" ] as ? US>String{
                        dataDescription="savedata1->\(savedata1), savedata2->\(savedata2)"
                    } else{
                        dataDescription="cannot retrieve data"
                    }
                    print("Document data:\(dataDescription)")
                } else{
                    print("Document does not exist")
                }
            }

Alternatively, it would be easier to re-use and the entire code would be refreshed if you defined the appropriate structure instead of the String type and passed the results to the @State variable of that type.
 However, using the FirebaseFirestoreSwift can make it easier because you can use a method that allows you to convert to a structure like Codable.(It was still in beta.)

About .

It is recommended that you obtain a "textbook of proper language itself" to solve these questions.

The next book, called Swift Book, is written on the premise that it has only English and knowledge of many other languages, but if you want to program with Swift, you must read it.

The Swift Programming Language

(In addition to the web version, iBooks version is also available for free.)

Unfortunately, I don't know any good textbooks in Japanese, but I think it would be good to choose a good one (mostly good ones are thick) after looking at reviews.I have never seen any good sites in Japanese.(Some sites are well written.)

docRef.getDocument {(document, error) in...} statement (A)

docRef.getDocument(completion: {(document, error) in...})

is an abbreviation of the function call called Trailing Closure, where the {(document, error) in in...} part is a closure expression, passed to the completion: argument and called the getDocument.

document = document (B)

This should be interpreted along with the previous let and the previous if.The = symbol in the middle has no equivalence or assignment, just a delimiter, in addition to if-let, guard-let, and so on.But) while-let is also used.(It's called Optional Binding, but I don't know a good translation.)

When = on the right side of / is of the Optional type, check the value for nil or non-nil, and then make a condition determination and variable declaration that says let document on the left side is defined only for non-nil.This variable is valid only in the if statement and other conditional elements.
(Although some languages prohibit redefining variables with the same name as the outside variable, Swift is common for Optional Binding.)

"Options" and the mechanisms that handle them safely are among the top features of Swift, and they have influenced other languages the most.There are plenty of articles on the Internet, but there are only a handful of good ones, so try to find and study as good as possible.


2022-09-30 21:55

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.