5

Web App Authentication with Email Magical Links, SMS Security Codes, and Google...

 2 years ago
source link: https://code.melo.plus/p/auth-firebaseui-svelte
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.
neoserver,ios ssh client

Web App Authentication with Email Magical Links, SMS Security Codes, and Google Accounts Using FirebaseUI and Svelte

Jul 6

In a past post, I wrote about creating an essential web authentication workflow with Firebase and Vue. A reader suggested exploring an additional resource provided by Firebase called FirebaseUI. This post follows that suggestion.

FirebaseUI is an open-source UI library that sits on top of the Firebase SDK. It implements visual controls, navigation, and integration logic for web app authentication.

The main advantage of using it is to reduce coding effort and the number of bugs that always accompany new code.

Today we will use FirebaseUI to enable users to sign with the traditional email and password, but also with email magical links, SMS security codes, and Google accounts.

Prerequisites

Besides the Firebase SDK and the FirebaseUI libraries, we will build the web app using the Svelte framework. Reactive frameworks like Svelte simplify the instructions to sync UI with the application state.

You should be fine if you are familiar with the web stack (HTML, JS, and CSS) or some other web framework like Vue, Angular, and React.

In the last section, I mentioned a previous post that took the time to create a minimal auth experience using Firebase and Vue but without relying on FirebaseUI. You don’t have to read that post to understand this one. Even so, starting there could be more helpful if you are unfamiliar with Firebase Authentication.

A machine with Node.js and a code editor like Visual Studio Code are the only requirements to code along.

Nevertheless, please say in the comments If you find that any topic lacks more explanation. I will try to help the best way I can.

Up and Running

Our first milestone is to have the skeleton of our web application running.

We start by creating a project folder to hold the source code. Inside the new folder, run the following command to initialize an npm package.

npm init -y

The browser does not understand Svelte files. Vite will compile and serve our code as development goes on. Please install our development dependencies.

npm i -D vite svelte @sveltejs/vite-plugin-svelte 

We instruct Vite to support Svelte with a vite.config.js file.

https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fa135c988-a4e7-422c-90df-8e6a0c8c9230_523x413.gif

Our web app requires an entry point. Time to create the index.html file with boilerplate markup to replace later.

Next, to ensure the plumbing is all set, run Vite with the npx vite command and check if the app is online at the address provided on the terminal.

https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ffedbfba4-159e-40d4-82c8-70f685048953_523x371.gif

Svelte (like other component-based frameworks) abstracts the UI in a component tree, starting with a root component representing the whole app.

We create the app.sveltefile to source a root component. For now, we leave it with a placeholder message. Then we update the index.html file to bring the root component from app.svelte and render it a target div.

https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F00a2fc37-aec7-4fea-9025-ba040c554830_523x360.gif

Sweet 😎. Now we move to Firebase.

Firebase

Now we go to the Firebase console to create new a project, activate a web app inside the project, and bring the configuration data into a new firebase.config.js file in our source code.

https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F55d2d092-ec72-4112-bca6-21cb6233b6cc_523x520.gif

With that covered, please go back to the Firebase site and click on the authentication service link. Choose the get started option and click on the email/password button. Enable email/password and email link on the next page and save. Also, enable phone and google providers with their default configuration.

https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F3a900397-eafc-416e-af98-866592123962_523x520.gif

Firebase is ready for our web app now. Let’s code the integration on the frontend side.

Integration

Our app requires a logic layer that receives data and actions performed by the user and communicates with the Firebase authentication service to establish new states like the user is now signed in or signed out.

We use two firebase packages to do the heavy work for us. The first is the firebase SDK which encapsulates the communication between our web app and Firebase services. Secondly, the firebaseui package will render the visual controls regarding the sign-in while driving the SDK.

So open a new terminal window (without closing the one where the Vite process is running) and install both libraries.

npm i firebase firebaseui

Our web app components will need three functions to take advantage of those libraries’ resources. The first function starts and passes the control to FirebaseUI, another for signing out (which is not covered by FirebaseUI), and the last to execute callbacks whenever the auth state changes.

Please create an firebase.auth.js file to make it a central place to expose those functions mentioned before. There, we initialize the Firebase connection and, for now, leave the functions with boilerplate code that we will replace as needed in the following sections.

https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F919bca50-e53b-4182-ba81-442a048c43d8_523x520.gif

Let’s consider how our app should behave regarding its two primary states. On the one hand, if the user is signed in, we must show a welcome page with business data and an option to sign out. On the other hand, if they are signed out, they should see a sign page with the controls provided by FirebaseUI.

We can subscribe to a Firebase trigger that fires every time this auth state changes, no matter the mechanism. The trigger will invoke a callback we provided upon subscription, passing the user profile data (if signed in) or null (in case of sign-out).

With that, we can develop a centralized solution at the root component to decide which of the two app pages appears.

To support that central switch, we will need to expose the capacity of the onChange function at the firebase.auth.js file. It must support the invocation of arbitrary callbacks whenever Firebase detects a state change.

Last, we build a dummy version of the PageSign and PageWelcome components. With that covered, we can see a glimpse of our app.

https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F6d265856-929b-483b-8c09-4cd4b0446dcb_523x520.gif

At the root component, Svelte takes care to rerender the template when the status value updates. This reactive pattern put together with the if and else blocks guarantees that the app shows correct content based on auth state.

Time to put FirebaseUI to work.

FirebaseUI

Since the root component will render PageSign when the user is signed out, that will be the place to ask FirebaseUI to control the app flow.

First, we should update the startUI function exported from the firebase.auth.js file to do just that. It envelops the FirebaseUI start function and exposes the feature in a pre-configured form.

The start function from the FirebaseUI library takes two arguments. The first is the element id which will contain the library’s pre-made user interface, and the second is a configuration object with a flexible list of options.

As FirebaseUI configuration options go, we need to inform the target providers: email, phone, and google. We also set the signInSuccessWithAuthResult callback to do nothing and return false. Our web app needs this awkward callback behavior so FirebaseUI does not redirect (forcing a refresh) after completing the sign-in process.

https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F7d2984a0-3182-4ded-b314-282f64bc34a6_523x520.gif

Next, we return to the page-sign.svelte file and create an empty div containing the FirebaseUI magic. We use the Svelte onMount hook to execute the startUI function. The hook runs instructions once at the beginning of a component lifecycle.

https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F47ba86e6-e3fa-44d4-be42-d56620934044_523x520.gif

The number of features we gain when putting these libraries together is impressive. I can only imagine the wonders you folks will build on top of that.

Hi, a small break to say that you can subscribe for free and never miss new posts from the blog.

Welcome

Now that users can sign in, we could improve our welcome page to show some data about the user and enable sign-out.

First, since the root component already passes down the user email and id values, we need to declare them as properties in the PageWelcome component so we can refer to them in the template.

Next, we update the signOut function in the firebase.auth.js file. Then import it inside the PageWelcome component. With that settled, tie the function to the click event of a button in the PageWelcome template.

https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F44757b1c-8139-4e2c-a14f-8ebed0e54cf3_523x520.gif

Our tutorial is good as done. You can refer to the complete source code here.

UI Libraries

I’m always mesmerized by how fast we deliver professional-looking experiences using component libraries like FirebaseUI. It also makes me remember my first days developing for the web and how Bootstrap helped me alleviate the backlog of new things to learn.

You see, the web is made of so many moving parts. It’s easy to get overwhelmed by a gigantic learning roadmap, and new things are constantly popping up. In my opinion, this role as a stepstone in the learning path to senior skills is the main advantage of using such component libraries.

I don’t embrace their speed in development so much for projects with a long-term perspective. After some years in the industry, I came to the opinion that the trade-offs in rigidity eclipse the legitimate gains in dev speed. That does not include short-term apps like those made for hackathons or prototypes.

In my experience, always comes the moment when we must implement something the library can’t offer. Then you need to reproduce its look and feel in a new component. Perhaps its version starts to conflict with crucial elements like the underlying framework. You will now need to replace or freeze the version of one of them. Those problems are hard to solve and hinder app sustainability.

Nevertheless, take my opinions with a grain of salt. These open-source projects have helped millions in our community (including me) for free over the years. Their maintainers deserve a lot of respect.

The personal lesson I want to share is this: be aware of the trade-offs involved when deciding to use a UI library versus building your components.

I would love to learn what you think about the subject and the post in general. Please share your thoughts in the comments.

If you think this post can help someone, please share it with them. Better yet, subscribe for free and receive fresh content in your inbox whenever it is published on the blog. I will never send more than one email a week.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK