Building an Ionic App with Firebase Authentication & File Upload using Angul...
source link: https://devdactic.com/ionic-firebase-auth-upload/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Building an Ionic App with Firebase Authentication & File Upload using AngularFire 7
February 22, 2022 By Simon 3 Comments
If you want a full blown cloud backend for your Ionic app, Firebase offers everything you need out of the box so you can setup your Ionic app with authentication and file upload in minutes!
In this tutorial we will implement the whole flow from connecting our Ionic app to Firebase, adding user authentication and protecting pages after a login to finally selecting an image with Capacitor and uploading it to Firebase cloud storage!
All of this might sound intimidating but you will see, it’s actually a breeze with these tools. To handle our Firebase interaction more easily we will use the AngularFire library version 7 which works with the Firebase SDK version 9 which I used in this post.
Get the Code.
Receive all Ionic code files directly to your inbox!
Note: At the time writing there was a problem when running the app on iOS devices – read until the end for a solution!
Creating the Firebase Project
Before we dive into the Ionic app, we need to make sure we actually have a Firebase app configured. If you already got something in place you can of course skip this step.
Otherwise, make sure you are signed up (it’s free) and then hit Add project inside the Firebase console. Give your new app a name, select a region and then create your project!
Once you have created the project you can see the web configuration which looks like this:
If it’s a new project, click on the web icon below “Get started by adding Firebase to your app” to start a new web app and give it a name, you will see the configuration in the next step now.
Leave this config block open just for reference, it will hopefully be copied automatically later by a schematic.
Additionally we have to enable the database, so select Firestore Database from the menu and click Create database.
Here we can set the default security rules for our database and because this is a simple tutorial we’ll roll with the test mode which allows everyone access.
Because we want to work with users we also need to go to the Authetnication tab, click Get started again and activate the Email/Password provider. This allows us to create user with a standard email/ps combination.
The last step is enabling Storage in the according menu entry as well, and you can go with the default rules because we will make sure users are authenticated at the point when they upload or read files.
The rules should look like this:
Note: For real applications you need to create secure rules for storage and your Firestore database, otherwise people can easily access all your data from the outside!
You can learn more about Firebase and security rules inside the Ionic Academy.
Starting our Ionic App & Firebase Integration
Now we can finally begin with the actual Ionic app, and all we need is a blank template, an additional page and two services for the logic in our app:
Besides that we can already install the Capacitor camera package to capture images later (and the PWA elements for testing on the browser).
To use those PWA elements, quickly bring up your src/main.ts and import plus call the defineCustomElements
function:
The last command is the most important as it starts the AngularFire schematic, which has become a lot more powerful over the years! You should select the according functions that your app needs, in our case select Cloud Storage, Authentication and Firestore.
After that a browser will open to log in with Google, which hopefully reads your list of Firebase apps so you can select the Firebase project and app your created in the beginning!
As a result the schematic will automatically fill your environments/environment.ts file – if bot make sure you manually add the Firebase configuration from the first step like this:
On top of that the schematic injected everything necessary into our src/app/app.module.ts using the new Firebase 9 modular approach:
Again, if the schematic failed for some reason that’s how your module should look like before you continue!
Now we can also quickly touch the routing of our app to display the login page as the first page, and use the default home page for the inside area.
We don’t have authentication implemented yet, but we can already use the AngularFire auth guards in two cool ways:
- Protect access to “inside” pages by redirecting unauthorized users to the login
- Preventing access to the login page for previously authenticated users, so they are automatically forwarded to the “inside” area of the app
This is done with the helping pipes and services of AngularFire that you can now add inside the src/app/app-routing.module.ts:
Now we can begin with the actual authentication of users!
Building the Authentication Logic
The whole logic will be in a separate service, and we need jsut three functions that simply call the according Firebase function to create a new user, sign in a user or end the current session.
For all these calls you need to add the Auth reference, which we injected inside the constructor.
Since these calls sometimes fail and I wasn’t very happy about the error handling, I wrapped them in try/catch blocks so we have an easier time when we get to our actual page.
Let’s begin with the src/app/services/auth.service.ts now and change it to:
That’s already everything in terms of logic. Now we need to capture the user information for the registration, and therefore we import the ReactiveFormsModule
in our src/app/login/login.module.ts now:
Since we want to make it easy, we’ll handle both registration and signup with the same form on one page.
But since we added the whole logic already to a service, there’s not much left for us to do besides showing a casual loading indicator or presenting an alert if the action failed.
If the registration or login is successful and we get back an user
object, we immediately route the user forward to our inside area.
Go ahead by changing the src/app/login/login.page.ts to:
The last missing piece is now our view, which we connect with the formGroup
we defined in our page. On top of that we can show some small error messages using the new Ionic 6 error slot.
Just make sure that one button inside the form has the submit type and therefore triggers the ngSubmit
action, while the other has the type button if it should just trigger it’s connected click event!
Bring up the src/app/login/login.page.html now and change it to:
And at this point we are already done with the first half of our tutorial, since you can now really register users and also log them in.
You can confirm this by checking the Authentication area of your Firebase console and hopefully a new user was created in there!
For a more extensive login and registration UI tutorial you can also check out the Ionic App Navigation with Login, Guards & Tabs Area tutorial!
Uploading image files to Firebase with Capacitor
Just like before we will now begin with the service implementation, which makes life really easy for our page later down the road.
The service should first of all return the document of a user in which we plan to store the file reference/link to the user avatar.
In many tutorials you directly create a document inside your Firestore database for a user right after the sign up, but it’s also no problem that we haven’t done by now.
The data can be retrieved using the according docData()
function – you can learn more about the way of accessing collections and documents with Firebase 9 here.
Besides that we can craft our uploadImage()
function and expect a Photo object since this is what we get back from the Capacitor camera plugin.
Now we just need to create a path to where we want to upload our file and a reference to that path within Firebase storage.
With that information we can trigger the uploadString()
function since we simply upload a base64 string this time. But there’s also a function to upload a Blob in case you have some raw data.
When the function is finished, we need to call another getDownloadURL()
function to get the actual path of the image that we just uploaded.
This information is now written to the user document so we can later easily retrieve it.
All of that sounds challenging, but it’s actually just a few lines of code inside our src/app/services/avatar.service.ts:
In the end, we should therefore see an entry inside Firestore with the unique user ID inside the path and the image stored for that user like in the image below.
Now let’s put that service to use in our page!
First, we subscribe to the getUserProfile()
function as we will then get the new value whenever we change that image.
Besides that we add a logout function, and finally a function that calls the Capacitor camera plugin. The image result will be passed to our service which handles all the rest – we just need some loading and error handling in here again!
Therefore go ahead now and change the src/app/home/home.page.ts to:
We’re almost there!
Now we need a simple view to display either the user avatar image if it exists, or just a placeholder if we don’t have a user document (or avatar image) yet.
That’s done pretty easily by changing our src/app/home/home.page.html to:
To make everything centered and look a bit nicer, just put the following quickly into your src/app/home/home.page.scss:
And BOOM – you are done and have the whole flow from user registration, login to uploading files as a user implemented with Ionic and Capacitor!
You can check if the image was really uploaded by also taking a look at the Storage tab of your Firebase project.
If you want the preview to show up correctly in there, just supply the right metadata during the upload task, but the image will be displayed inside your app no matter what.
Native iOS and Android Changes
To make all of this also work nicely on your actual native apps, we need a few changes.
First, go ahead and add those platforms:
Because we are accessing the camera we also need to define the permissions for the native platforms, so let’s start with iOS and add the following permissions (with a good reason in a real app!) to your ios/App/App/Info.plist:
For Android we need to do the same. Therefore, bring up the android/app/src/main/AndroidManifest.xml and after the line that already sets the internet permission add two more lines:
Finally when I ran the app on my device, I just got a white screen of death.
There was a problem with the Firebase SDK and Capacitor, but there’s actually an easy fix.
We only need to change our src/app/app.module.ts and use the native authentication directly from the Firebase SDK when our app runs as a native app:
Because of the modular approach this change is super easy to add, and now you can also enjoy the Firebase app with upload on your iOS device!
Conclusion
Firebase remains one of the best choices as a cloud backend for your Ionic application if you want to quickly add features like user authentication, database or file upload.
For everyone more into SQL, you should also check out the rising star Supabase which offers already all essential functionality that Firebase has in an open source way.
You can also find a video version of this tutorial below.
Get the Ionic 6 Quickstart Guide
Build your first Ionic app for iOS, Android & web using Capacitor in no time!
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK