Hi guys,
retrieve Data from a single Document works fine, but now I want to have a Textfield where the User can search for a single Document inside my Firestore Database.
FireStoreManager.swift:
import Firebase
import SwiftUI
class FirestoreManager: ObservableObject {
@Published var name: String = “”
@Published var elevation: String = “”
@Published var runway: String = “”
@Published var searchairport: String = “”
init() {
    fetchRestaurant()
}
func fetchRestaurant() {
    let db = Firestore.firestore()
    let docRef = db.collection("Airports").document(searchairport) 
                  // variable for searching the airport ???
    docRef.getDocument { (document, error) in
        guard error == nil else {
            print("error", error ?? "")
            return
        }
        if let document = document, document.exists {
            let data = document.data()
            if let data = data {
                print("data", data)
                self.name = data["name"] as? String ?? ""
                self.elevation = data["elevation"] as? String ?? ""
                self.runway = data["runway"] as? String ?? ""
            }
        }
    }
}  
}
ContentView looks like this:
struct ContentView: View {
@EnvironmentObject var firestoreManager: FirestoreManager
var body: some View {
   
    
    TextField("Enter Airportname", text: $searchairport )
    
    Text("ICAO: \(firestoreManager.name)")
    Text("Elevation: \(firestoreManager.elevation)")
    Text("Runway: \(firestoreManager.runway)")
        .padding()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
.environmentObject(FirestoreManager())
}
}
My Firestore looks like this
             
            
              
              
              
            
           
          
            
            
              In my opinion, a better way to do this is to allow Firebase to create a record using the Auto documentID process rather than going to the trouble of specifying a specific document ID since you run the risk of creating a duplicate documentID accidentally.  They are supposed to be unique.
See this firebase screenshot example:
Ignore the fact that in the above example airports is not capitalised
In your ObservableObject your createAirport function could be like this:
    func createAirport(name: String, elevation: String, runway: String) {
        let db = Firestore.firestore()
        db.collection("Airports").addDocument(data: [
            "name": name,
            "elevation": elevation,
            "runway": runway
        ])
    }
Then your fetchAirport function (I named the function fetchAirport because it’s not a restaurant) would be something like this:
    func fetchAirport() {
        let db = Firestore.firestore()
        let query = db.collection("Airports")
            .whereField("name", isEqualTo: searchAirport)
        
        query.getDocuments { snapshot, error in
            guard error == nil, snapshot != nil else {
                print("Error: \(error?.localizedDescription ?? "")")
                return
            }
            // Assuming that the Airport ID is always going to be unique
            //  there will only be 1 record
            for doc in snapshot!.documents {
                self.name = doc["name"] as? String ?? ""
                self.elevation = doc["elevation"] as? String ?? ""
                self.runway = doc["runway"] as? String ?? ""
            }
        }
    }
This is a query where the documents are searched to find a match where the name field is equal to the search criteria.
I hope that helps.
             
            
              
              
              2 Likes
            
           
          
            
            
              Hi Chris,
thank you for the better approach with the query and the equal to.
Do I need to connect my variable searchAirport in the Textfield with a button to start the search query  in the ContentView() ?
struct ContentView: View {
@EnvironmentObject var firestoreManager: FirestoreManager
var body: some View {
   
    
 TextField("Enter Airportname", text: $firestoreManager.searchAirport)
  //Searchfield with the variable which is equal to name
 Text("ICAO: \(firestoreManager.name)")
 Text("Elevation: \(firestoreManager.elevation)")
 Text("Runway: \(firestoreManager.runway)")
        .padding()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
.environmentObject(FirestoreManager())
}
}
             
            
              
              
              
            
           
          
            
            
              I just got it to work with a button
Thank you so much for your help Chris. I am happy that my project comes finally alive 
Solution
struct ContentView: View {
@EnvironmentObject var firestoreManager: FirestoreManager
@State private var searchAirport: String = “”
var body: some View {
   
    
    TextField("Enter Airportname", text: $firestoreManager.searchAirport)
    
    Button {
        firestoreManager.fetchAirport()
        
    } label: {
        Text("Save Airport")
           
    }
             
            
              
              
              
            
           
          
            
            
              
The other way you can do this is use the .onSubmit modifier on the TextField which responds to when you press the return key.
ie:
TextField("Enter Airportname", text: $firestoreManager.searchAirport)
    .textInputAutocapitalization(.characters)
    .textFieldStyle(.roundedBorder)
    .onSubmit(of: .text, {
        // This responds to pressing return on the TextField
        firestoreManager.fetchAirport()
    })
The other two modifiers:
.textInputAutocapitalization(.characters) converts all alphabetic entries to uppercase (very handy since your airport identifiers are uppercase) and
.textFieldStyle(.roundedBorder) just makes the TextField look a bit nicer on the screen as per this example code I set up to test the code I provided you previously.

             
            
              
              
              2 Likes
            
           
          
            
            
              Thank you for the tips and hints, I implemented them for better comfort. 