0

I'm creating a customer management app for iOS. I'm using Firebase to store data and files. My app have multiple view, in main view are the customers and the second for saving documents and display and the third is where you can add some callDetails what you speak last time with this customer.

So far I can save data in Firestore and files in storage and display them.

My problem is how can I structure the database that each document point to the right customer and same for callDetails. I know that I need to add references in the customer collection like Nested Data for example but I'm stuck with this. So how can I save a reference to customer collection and then fetch the data?

I refer to this article but no luck: https://peterfriese.dev/posts/firestore-codable-the-comprehensive-guide/

CustomerStruct.swift

struct Customers: Identifiable, Codable {
    @DocumentID var id: String?
    var fullName: String
    var phoneNum: String
    var email: String
    var address: String
    var profession: String
    var age: String
    var dateOfBirth: String

    enum CodingKyes: String, CodingKey {
        case id
        case fullName
        case phoneNum
        case email
        case address
        case profession
        case age
        case dateOfBirth
    }
}

LastCallStruct.swift

struct LastCallData: Identifiable, Codable {
    @DocumentID var id: String?
    var title: String
    var description: String
    var date: String

    enum CodingKyes: String, CodingKey {
        //case id
        case title
        case description
        case date
    }
}

this is how i save the customers data the same is for callDetails

let newCustomers = Customers(
    fullName: nameTextField.text!,
    phoneNum: phoneTextfiled.text!, 
    email: emailTextField.text!,
    address: addressTextField.text!, 
    profession: professionTextField.text!, 
    age: ageTextField.text!, 
    dateOfBirth: dateOfBirthTexField.text!)

do {
    try self.db.collection("...Customers").addDocument(from: newCustomers)
} catch let error {
    print("Error writing data to firestore,\(error)")
}

This is how I fetch customers and the same for callDetails

func loadCustomers(){
    db.collection(self.collectionName).addSnapshotListener { (QuerySnapshot, error) in
        self.customerArray = []
        if let error = error{
            print("Error geting documents,\(error)")
        } else {
            for document in QuerySnapshot!.documents{
                print("\(document.documentID) => \(document.data())")
                let data = document.data()
                if let customerName = data["fullName"] as? String, let customerNumber =
                    data["phoneNum"] as? String {
                    let newCustomer = Customers(id: document.documentID,fullName: customerName, phoneNum: customerNumber, email: "", address: "", profession: "", age: "", dateOfBirth: "")
                    self.customerArray.append(newCustomer)
                    
                    DispatchQueue.main.async {
                        self.tableView.reloadData()
                    }
                }
            }
        }
        
    }
}

This is how i save document data in storage and put a reference in a new collection but i want this to point to customer collection

private func handleFileSelection(inURL:URL) -> Void {
    // let filePath = inURL.deletingPathExtension().lastPathComponent
    filePath = inURL.pathComponents.last!
    // file Storage reference path
    let path = "customer name/\(filePath)"
    let files = storage.reference().child(path)
    do {
        let data = try Data(contentsOf: inURL)//Geting file here
        //Upload the data for the specific file in firebase
        files.putData(data, metadata: nil) { (metadata, error) in
            //Save a reference into firestore

            self.db.collection("Documents").document().updateData(["url": path])
            guard metadata != nil else {
                print("Error while uploading data, \(String(describing: error))")
                return
            }

            files.downloadURL { (url, error) in
                //Download the file URL
                let urlString = url?.absoluteString
                print("Dowloaded URL: \(String(describing: urlString))")
            }
            print("Success")
        }
    } catch {
        print("Document loading error")
    }             
}

This is how my database looks like

enter image description here

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • 2
    FYI the correct spelling is "Customer" unless you're creating a database of people who create fancy costumes for theatrical productions? – Fogmeister Jul 13 '22 at 09:55
  • My mistake it is exactly as you say because it will be an app for customer management – Mariglen Meta Jul 13 '22 at 10:20
  • Rather than have a separate `lastCallDetails` collection, I would create a `callDetails` collection under each document in your `Customers` collection. Then you would create a document in that collection for each call. So you would have some thing like `Customers/2LIPFnA5cSJTqQS113d1/callDetails/123hchhfhjhcxvjhvjhjcv` where `2LIPFnA5cSJTqQS113d1` is the document id of a customer and `123hchhfhjhcxvjhvjhcv` is the document id of a `LastCallData` document for that customer. This way your calls are associated with the relevant customer – Paulw11 Jul 13 '22 at 10:23
  • No worries. :D Just a typo so easy for you to fix. It wouldn't fix the issue you're having though, just wanted to help out. :D – Fogmeister Jul 13 '22 at 10:23
  • @Paulw11 This may be a good way structuring the database and make the relation I want. But in one view I display only the callDetails and in the another view I display all the uploaded files. So in this way I need to create two collection under Customer collection. – Mariglen Meta Jul 13 '22 at 10:34
  • In general you should forget about using "references". Firestore is a NoSQL store. If you try and make it work like an SQL database you will find it difficult. Things will work out better if you use sub collections as I have suggested. If you do not want to use sub collections then you can simply store the document id of the related in customer in each call document and store an array of document ids for the related calls in each customer document. – Paulw11 Jul 13 '22 at 10:47
  • But it is probably easier just to retrieve all customers and all call sub collection documents for your calls view – Paulw11 Jul 13 '22 at 10:55
  • @Paulw11, I will take a look and make some search for each of the suggestions you made to me because it is my first time using NoSQL database. I have worked only with SQL database. Thank you for helping me! – Mariglen Meta Jul 13 '22 at 10:59
  • I will see now how to make the CallDetils a sub collection of Customer collection. – Mariglen Meta Jul 13 '22 at 11:00
  • @Paulw11, Your idea with sub collection solved my problem. Thanks a lot – Mariglen Meta Jul 13 '22 at 12:13
  • Nice to hear your issue got resolved. It will be helpful for the Community members if you can post an answer – Sandeep Vokkareni Jul 14 '22 at 06:29
  • My issue was solved by using sub collection and I learned how to create sub collection in this link: https://stackoverflow.com/questions/47514419/how-to-add-subcollection-to-a-document-in-firebase-cloud-firestore. Every callDetails now is related to exact customer – Mariglen Meta Jul 14 '22 at 07:55

0 Answers0