E-Commerce App using Firebase services Part I

E-Commerce Apps are the most requested apps in your CV as an iOS Developer; that’s why this article will help you make a full E-Commerce App from scratch using Firebase. Before getting started, you need to understand the differences between using firebase services and Restful APIs.

What is Firebase?

Firebase is a backend as a service that Google provides. Firebase has many services like Firebase Database, Firebase Storage, Firebase Authentication, Firebase Realtime Database, Machine learning & Hosting. You can also use other services provided by google inside your App to avoid crashes, like using google crashes analytics, etc.

And, of course, nothing is coming for free, which means that all of these services have limits. Once you pass these limits, you will be forced to pay to continue using these services. Your payment will be dependent on your app usage, each one of the previous services has its usage, plus you don’t need to use all of these services. It depends on your App; for example, you will use Firebase Realtime Database when you decide to create a chatting application; on the other side, most of the apps are using Firebase Authentication to be able to log in or register, and it gives you so many options to register or login with like Email, Mobile number, Facebook, Apple, Google, etc.

You can use Firebase Database to save the normal data like users’ data, some links, and to cut it short, you can also use it to save any written data. On the other hand, if this data points to an image for example you will need to use Firebase Storage to be able to save this image data.

From Firebase and its service to Restful APIs ➡︎

Restful API is an application programming interface (API or web API) that conforms to the constraints of REST architectural style and allows for interaction with RESTful web services. An API is a set of definitions and protocols for building and integrating application software.

An API can be used in many ways and a developer can develop it, you can also find ready-to-use APIs and test them like Africa’s Talking API’s, Youtube API Check this article, etc.

Let’s get started.

The first step is to install firebase and connect it to our app, let’s suppose that our App is called “ECommerceApp.

Step1: Open Firebase

Step2: Create a new project like the image:

Step3: It will direct you to the page to write the app name “ECommerceApp”:

Step4: Disable Google Analytics for the project as we won’t use it and click on create project.

It will direct you to the page where you can choose the platform you need to use firebase in; in our case, we will select iOS:

This will direct us to a new view that requires us to enter the bundle ID and the App name. If the app already exists on the App Store, we will write its ID:

We can get these attributes from our App:

You will then need to download GoogleService-Info.plist file and add it to your project:

Let’s get building now, first we need to install all the pods we need while working on the app:

1- In the terminal cd “Project Path”

3. pod init and open the Podfile

4. write pods names & Save the file

5. Type pod install in the terminal in the same path.

Finally, we then need to open the .xcworkspace file from the project directory.

We will open our AppDelegate.swift file, import Firebase then type FirebaseApp.configure() in the function: func application(_ application: UIApplication

Let’s start creating our design for the Home page, first create a file called HomeViewController.swift, we will then work on the design in our storyboard.

We embed our viewController in the navigationController then we will embed it in the tabBarController :

After creating HomeViewController.swift as we said before we need to connect it with the view:

We will then start to add collectionView with some cells and each cell contains the name and the

image for each category.

The collectionView will have some constraints by clicking on the collection view after dragging and dropping it into our viewController then follow the image below:

And you can check & change these constrains from the right top called Size Inspector, don’t forget to connect the delegate and the data source between the collectionView and the viewController by clicking Ctrl + drag to the entry point like the image:

Then we will create the custom xib cell file called HomeCell

Now we have two files related to the cell HomeCell.swift & HomeCell.xib and we will just use HomeCell.swift to connect our outlets but first we will add imageView and label from the library as we did before in CollectionView into HomeCell.xib and don’t forget to set the cell identifier for our cell and it preferred to be the same name as the name of the class which is HomeCell:

Taking outlets for imageView and label by using alt + the file we need to connect with which is HomeCell.swift and then you will click on the item you need to connect even if it’s the label or image view and write its name like in the image:

let’s go more into our code and create our Category.Swift Model but first we will create an enum to be able to use it while using firebase to be able to control our database, this file will be named FBCollectionReferences.swift and the code in the file is:

In the previous code, we make an enum to be able to set each group in a separate collection and as we will have 4 collection or models we will use we set each one of them in our code, and then we created a function to be able to return this collection dependent on our class or model.

before moving to Category.swift we need to create Constants.Swift file to add our constants depend on each model so starting by Category, we have category name, image, image name, ID:

Constants.swift

Moving to Category.swift

in the last code I’ve created a class Category with its variables and then make an init for it to initialize the values and next I will create init but it takes and saves values from and into dictionaries using our constants:

After creating this we need to create a function to to take a category and then transform it into dictionary as firebase deals with dictionaries only:

we used NSCopying to be able to copy the values into our constants, then we will save our categories into firebase:

we’ve created a random string ID and saved it as CategoryID and used my category to be saved into our Category collection which initialized in FBCollectionReferences.swift file and then we document it with the ID and finally setting the data into a category dictionary to be able to be saved into firebase.

After that we need to create a function to be able to create our categories only one time at the first time to run the App as it will be fixed always and will be never changed

Note: all categories images will be added to the assets file

We’ve created each category with its initializer by adding its name and image name, then we’ve added all of these categories into an array to save each element of this array into the firebase.

The only left function is the one we can use to download our categories from firebase:

As we did before, we used our collection reference function but here we’ve used .getDocuments with its closure instead of using .setDocument() and we will check the snapshot using guard to make sure that this snapshot has a value then we checked if the snapshot not empty to be able to loop on it to get each category dictionary and finally return it in the completion.

Now we will start creating our HomeViewController

HomeViewController.swift

In the first MARK statement, I’m using prepareforSegue function to be able to mark each category with its specific items. Don’t worry we will create our ItemsListViewController after a while.

In the second MARK statement I’m using loadCategories function to call the main function mentioned in the model to be able to add all the categories inside our variable array which is categoriesArray and finally, we will reload our categoriesCollectionView but there is a very important note to avoid warnings and errors.

You have to use DispatchQueue.main.async to be able to reload the collectionView on the main thread.

In the previous MARK statement, I’ve used UINib to be able to connect the cell to its collectionView and before it I’ve connected the collectionView with its controller through IBOutlet to be able to use it and finally, I’ve called two functions the first one is createCategories() and it’s commented as you must call it only once to avoid any conflict and the second one is loadCategories()which is the function I’ve created before to download the categories from firebase at each time the app is opened.

In the previous block of code, I’ve used the collectionView methods, in the first function I’ve returned the count of the categoriesArray which was initiated before in the loadCategories() and in the second function cellForItemAt I’ve created a cell from my previous HomeCell and used it to be able to give labels text and image in the imageView from each category in the array but don’t forget to put this line before your class to be able to use it at any file in the code:

and finally, we will create our items list the same as we did before in the collectionView but here we will add tableView and we will connect our HomeViewController with ItemsListViewController using segue as mentioned before through images from left to the right:

Now we can check the last function in collectionView methods where I used the identifier of the segue and send it related to each item in the array.

Only one thing left to do which I’m using to be able to control the size of my cells in the collectionView only which is mentioned below:

In the previous blocks, I’ve just initiated the insets variable which indicates the items needed per row and the padding constraints for each one then we will use this in the extension by deducting the padding space from the width of the view and then divide it by the items per row to be able to detect each item’s width.

After finishing HomeViewController I will start working on ItemsListViewController but first, we will create an item model and add item constants to the constants file:

Item.swift

I’ve just created some variables related to each item and all of them are mandatory, then I’ve created my inits and one is empty because all of the properties are mandatory then I used the second init with dictionary and constants as before in Category.Swift, let’s add these constants in Constants.swift

Then I’m gonna add some functions related to item as I did with category:

As I did in category I’m doing the same here, first of all, I’m transforming the item to the dictionary to be able to save it in firebase using the fromItemToDict(myItem: Item) function, then I’ll save the item in firebase using saveItemToFB(myItem: Item) by using the FBCollectionRefrence function and item ID and finally I’ll be able to download the item from firebase by using the dictionary init and transform each document in the snapshot into the item and return it in the completion().

Now I need to create the itemCell to be able to connect it to our file, I will do the same as I did before in the HomeCell but the difference here that we will make it a table view cell not a collection view cell, after adding the appropriate constraints we will have the following image:

In the previous image I’ve added three labels (item name, price, and few lines from description) and one image view to show the item main image, don’t forget to connect each one to its IBOutlet, and no need for all the rest of code which initiated by default in the file, the cell identifier is the same as a class name which is: ItemCell and it will be the first thing mentioned in ItemsListViewController.swift

ItemsListViewController.swift

As mentioned before I’ve initiated the cell identifier and the outlet for the tableView like we did before in collectionView, then I will create my variables:

The first one is to be able to pass the category through controllers as we did in segue & the second one to be able to pass it to show items in the tableView and now I will use ViewDidLoad() function:

I have configured the cell with the tableView using UINib()then checked the category to make sure it has a value and now you can test it by showing its name as a title on the view, after that, I will create a function to load items in it and call it in viewDidAppear() to load the items at each time the view will appear and we used it not viewDidLoad() once we add an item we wanna see it in our items without closing and opening the app again.

After doing all of that I wanna create a ItemDetailsViewController to be able to show each item details and after creating it I will add an instance from the item in ItemDetailsViewController like I did before in category to be able to use and pass it through views:

backing to ItemsListViewController:

I’m telling the XCode to pass myItem from this controller to the controller it’s moving to which is ItemDetailsViewController then show this view and I will call this function in didSelectRowAt() the function which will be included in the next block of code which contains tableView methods:

Here I’ve used the itemsArray to return its count and then used each element in it to be able to access its attributes and used kf with imageView to download the image using KingFisher Pod and finally I’ve called showItemDetails() function as I mentioned before, the last thing left now is to use EmptyDataSet_Swift by adding these attributes in ViewDidLoad():

Then create extension to use it:

In this extension there are three functions, one for title, one for image “It’s added in the assets” & the last one for description.

The question now is: How can I add an item as a user “Seller”? The answer is simply by using segue as before in category but first, you need to create the controller for adding items which called AddItemViewController then add barButtonItem as in the image:

Now I can navigate to the addItemViewController using the barButtonItem, now all I need to do is to start working on the two views and classes created before which are addItemViewController & ItemDetailsViewController starting with:

ItemDetailsViewController:

The first thing I always like to start with is the design and that’s why I’ve created the design in the first place to be able to work upon it:

In the previous image I’ve created a collection view to show images for each item then label for the name and one for the price and finally textView for the description and don’t forget to add a button to add it to the cart but we will work on it later, after setting the suitable constraints we will connect all of these to their views like before and don’t forget the variable I used before to access the item:

I will create function to set UI for each item in the view:

Someone will tell me to hold on and will ask about CurrencyConverter() the function which will be explained now, it’s a function used to be able to convert the double “Price” into a string to be able to set it on the label, I’ve created a group called Helpers and added a file into add to use it for some supportive functions:

Helpers.swift

In the previous block, I have used a built-in class to be able to transform the price and I need it to be currency and by a dollar sign and finally, I switched it into a string. Now as usual I will use ViewDidLoad() to show the item’s name and register the cell of the collectionView as we learned before and then calling my setupUI() function:

After that we need to use collectionView functions which are related to the images:

I’ve returned the number of the images in the item then use the images for each item to download and show it using kf “KingFisher Pod”, that I used collectionViewFlowLayout methods but first I added its variables and all of them is the same as we did before in HomeViewController:

Now I need to do the last view in this article which is AddItemViewController.swift but before start working on it you need to ask yourself a question which is: How can I upload images into firebase and that’s why we will add two functions related to images in Helpers.swift & don’t forget to import FirebaseStorage:

The first thing is importing FirebaseStorage to be able to use the storage and here I need to go to enable the access to be able to use it:

From storage, rules, remove the highlighted part and publish it, now I can explain the first function which is used to save the image to firebase by:

1- Transforming the image into data to be able to use it.

2- Creating an upload task to use it later.

3- Creating a reference for the image and putting its file into it.

4- Use the uploadTask created before to add imageData into it.

5- In the completion I removed all observers.

6- If there is an error, it will be printed

7- If there is no error, I will transform image data into url and return it in the completion.

In the second function I used it to upload images and called saveImagesToFB in it:

1- I passed array of images in the parameter

2- I’m looping on this array to transform each image in this array into data using jpegData with compression 0.5 to be easy to upload.

3- For each image, I’ve created a file for it using itemID and numberSuffix which is increased to differ each image from other images “The last line in the function”.

4- I used saveImagesToFB and pass the data created before to it.

5- After checking the link if it’s not nil it will be added to the array of links and counter increased by 1.

6- Once the counter equals the array counter which means that no more images left, the array of links will be returned in the completion.

After being aware of each detail in the previous function, let’s go to our view:

AddItemViewController.swift

Once I clicked on the add button ” + “, It will navigate me into add items view but it’s just for now, in the next article I will make it related to the login so you can’t add items if you don’t log in.

The view included two textFields one for item name, the other for the item price, textView for the description, and button to add multiple images, after adding the suitable constraints I connected each one to its outlet & added the variables used in the view, importing Gallery will help to take images from the gallery:

Don’t forget to add some lines to Info.plist after <dict> to be able to access images, the below lines allows you to show the user something like the message to take his/her access to be able to take images:

Then I used viewDidLoad() just to create the barButtonItem with its action and after it, I created a function to pop view instead of writing the line at each time:

Now I will show the function called in the rightBarButtonItem:

In the previous function:

1- I’ve created an instance from item.

2- I used a built in function to generate a random ID then each attribute will be put into its own UI item.

3- You will find a commented print statement which used only for testing.

4- If itemImages count greater than 0, I will start uploading these images and save the item to firebase.

5- If not I will only save this item in firebase.

6- To avoid any errors don’t forget to set a default image from the view, not the code, we can call it a “placeholder image”.

7- In all cases popView() will be called.

Now I used the action for addImage button:

I’ve only created an instance from GalleryController()then accessing its delegate (It may give you an error, will be fixed late)

Then I gave the user two options from gallery or camera but with a limit of 30 images per item and of course, nothing will be working without presenting the gallery.

The only thing left is to have an extension for the controller from the delegate of the gallery:

I need to work on the first function only which shows & presents my images, in all other functions and at the end of the previous function as well I only dismissed the gallery controller.

Finally Part I is done, wait for Part II which will include Login, Cart, etc…

Thanks for reading️! Help spread the word & wait for the coming articles 📝

Have questions, suggestions, comments, or ideas for upcoming blog posts? Contact me on LinkedIn or write a comment! You can also follow me on GitHub & check my Stackoverflow answers and questions.

0 Shares:
You May Also Like