12.7. Adding a New Contact
Let's focus on building the functionalities to add a new contact for a signed-in user in the app.
Let's add a new group in the file navigator, 'Add Contact Screen.' Create a file named 'AddContactViewController.swift' inside it.
Create a sub-group of 'Add Contact Screen' named 'Views' and create 'AddContactView.swift' file inside it.

AddContactView.swift
Let's open 'AddContactView.swift' file and write the following code there:
The above code is straightforward as well. We have four UI elements, three text fields for the contact's name, email, and phone, and an add button to store the contact.
AddContactViewController.swift
Open the 'AddContactViewController.swift' file. Now let's put the following code there:
In the above code:
We import the necessary libraries:
FirebaseAuth - to access the details of the current user
FirebaseFirestore - to store data
FirebaseFirestoreSwift - to upload/read data using Swift Codable structs.
On line 23, we say we prefer a small-sized title, not a large one.
On line 26, we add an action to the add button, and the action is defined in
@objc func onAddButtonTapped()method.On lines 30 through 45, we define
@objc func onAddButtonTapped()method.First, we validate the name, email, and phone number the user put in. Then we call
func saveContactToFireStore(contact: Contact)method to upload the contact to Firestore.
We now have to update the Contact struct a little bit to conform to the Firestore structure.
Then we will define
func saveContactToFireStore(contact: Contact)method.
Updating Contact.swift
Open DataModels -> Contact.swift and update it like the following:
In the above code:
We import FirebaseFirestoreSwift to encode and decode Swift objects to and from Firestore document objects. Each Swift Contact object will represent a contact document in Firestore.
We adopt the Codable protocol to enable encoding and decoding.
On line 12, you see that we added
@DocumentID var id: String?. Do you remember that Firebase has two options for setting a document ID? You can either give an ID manually or auto-generate an ID. We need to put that declaration line to enable both to conform properly to the Firestore document structure. We are saying that the document ID of the Firestore document will be an optional string. For more clarification visit: https://firebase.google.com/docs/firestore/solutions/swift-codable-data-mapping.
Uploading the Contact to Firestore
Now, let's put the following code to AddContactViewController.swift file:
In the above code:
On line 15, we instantiate constant
databasewith the Firestore database.databasenow points to the root document in Firestore.We are creating a reference to the collection for the contacts of the current user on lines 21 through 24. We are trying to access
On lines 21-22,
database.collection("users")to access theuserscollection where we have all the users.On line 23,
.document(userEmail)tries to access the document regarding the current user. We name (DocumentID) the document with their email address since the email will be unique to each user.On line 24,
.collection("contacts")tries to access the 'contacts' collection for that user document.
So basically "users" collection holds all the documents regarding the users. Each document refers to a user authenticated through FirebaseAuth. Inside each user document, we have another collection named "contacts" to hold all the contacts for that user.
collectionContactsrefers to this "contacts" collection.From lines 25 through 33, we handle storing the contact to Firebase. Here the do-try-catch block is necessary since this is a network call, and it might create errors when adding something to Firebase if we write data with a wrong structure.
On line 26, we call
collectionContacts.addDocument(from: contact, completion:...)to add a contact document tocollectionContactsreference. If you notice, we are directly uploading the data from a Swift Contact object.If there is no error, the add is successful, and we can now close this screen and go back to Main Screen.
Adding Progress Activity Indicator
We can easily add the progress indicator view when storing the contact in Firestore. Let's add the following code to AddContactViewController.swift:
In the above code:
On lines 46 through 58, we are adopting the
ProgressSpinnerDelegateprotocol to display the progress indicator.On line 25, we show the indicator before we start storing the contact in Firestore.
On line 31, we hide the indicator after we complete storing the contact.
Patching with the Main Screen
Once the floating add contact button is tapped, we need to display the add contact screen. So, let's add the following lines of code to ViewController.swift file:
In the above code:
In
viewDidLoad()method, we add an action tofloatingButtonAddContactbutton. The action is defined inaddContactButtonTapped()method.On lines 26 through 30, we populate the Add Contact screen.
Now, if we run the app, we will see:

If we look at the Firestore console, we will see the following:


You can see that:
The "users" collection contains a document called "[email protected]". Because the current user's email is "[email protected]."
The "[email protected]" document contains a collection named "contacts."
Inside the "contacts" collection, we have contact documents (with auto-generated IDs).
Inside each contact document, we have details of that contact as fields.
Last updated
Was this helpful?