Emilio Schepis
Emilio Schepis's Blog

Emilio Schepis's Blog

Developing Geonotes — Implementing authentication — Ep. 5

Developing Geonotes — Implementing authentication — Ep. 5

The next logical step before letting users submit their notes.

Emilio Schepis's photo
Emilio Schepis

Published on Aug 6, 2021

3 min read

Now that we can create notes like described in Episode 4, it is time to allow signed in users to create their own.

...except there is no authentication yet!

👤 Adding email & password authentication

The most straightforward way of authenticating is through email and password.

I created a very simple form with react-hook-form and yup for validation.

These library work out of the box with React Native and Expo. Once the form is submitted, a new Firebase user is created. This triggers the same Cloud Function that assigns the custom claims to new anonymous users.

⚙️ Generating a unique username

If the user being created is with email and password (so, not anonymous), the function now generates a unique username for the account.

The way this is done is by:

  • taking the part of the email before the at sign — Emilio!?=@hashnode.dev ➡️ Emilio!?=
  • sanitizing the various disallowed characters (letters, numbers and underscores) — Emilio!?= ➡️ emilio
  • generating a random four number digit and verifying if it's unique emilio ➡️ emilio1234

To verify whether or not a username is unique, a custom query is performed by filtering all usernames by the sanitized string (so that we don't have to load all usernames every time). Source

export async function generateUniqueUsername(email: string): Promise<string> {
  function generateRandomFourDigits(): string {
    return Math.floor(Math.random() * 10000)
      .toString()
      .padStart(4, "0");
  }

  const base = email.split("@")[0].toLowerCase();
  const sanitized = base.replace(/[^a-z0-9_]/, "");

  const usernames = (await sdk.Usernames({ like: `${sanitized}%` })).users.map((user) => user.username);

  let uniqueUsername = sanitized + generateRandomFourDigits();

  while (usernames.includes(uniqueUsername)) {
    uniqueUsername = sanitized + generateRandomFourDigits();
  }

  return uniqueUsername;
}

❌ The first roadblock

Ideally, I'd like to add Google and Apple authentications too. I have done it countless times, but this time I found an unexpected problem.

Since I'm using Expo, I need to go through the process of setting an OAuth screen for my Firebase project.

While playing around with the form in the Cloud console, I uploaded a random image as logo, only to find out you can't change it or remove it. What's worse is that since I uploaded an image, a verification process needs to happen, and it will take 4-6 weeks to verify that the logo is actually mine. Which it isn't, since I just uploaded the default placeholder.

I decided to put the issue on the back burner for the moment, and concentrate on finishing the basic functionality.

🚧 Next steps

Now that the main pieces are in place, I want to deploy the app for the first time on the actual production environment.

Before doing so, I want to setup a CI/CD pipeline using GitHub Actions to safely deploy all changes in a consistent way.

The actions will

  • Lint and build the code
  • Upload metadata & migrations to Hasura
  • Upload and update Cloud Functions on Firebase
  • Deploy the app to the correct release channel

🎙 How to follow the project

I'll be posting updates throughout the development process and as I learn new thing regarding development, design, and marketing.

If you'd like to have even more real-time updates you can

 
Share this