[AUDIO LOGO] PETER FRIESE: They say
there is no second chance to leave a first impression. And yet there are
so many apps that require creating an
account before you can even start using them. Asking users to
create an account and come up with a strong
password adds a lot of friction to the onboarding process. And many users won't even
end up creating an account. They will just
uninstall your app. Remember, on the app store, your
competition is just a tap away. So if you want more users to
give your app a fair chance and experience all the
amazing features you poured your heart into, you should
remove the speed bump and make the onboarding
process as smooth as possible. Hey, my name is Peter. I'm a developer advocate
on the Firebase team. And today I'm going
to show you how you can streamline the
onboarding process of your app and reduce the
number of people who uninstall your app before
even giving it a try. So why should you ask
your users to authenticate in the first place? Well, there are a
number of reasons. For example, you
might need a way to get in touch with your
users, for example, by email or by sending them an SMS. If you're developing an app for
a delivery service or a ride sharing app, you might even want
to be able to call your users. Another very common
reason is that you need some unique
identifier that you can use as a key
for the data you store in the app's back end. For example, if your app is a
cross-platform to-do list app, you want to make sure that your
app can tell the to-dos of all your users apart. It would be a
data-privacy disaster if someone else would be
able to see your to-dos, and vise versa. The same applies for
a bank that needs to make sure only the
account user gets access to that banking account. Another reason for putting up
an authentication speed bump might be to artificially
limit the number of people who can use the app
and create scarcity. Or maybe your app is an app in
front and for a resource that requires some form
of authentication, like the machines in a factory. All of these are valid
reasons for asking your users to sign in. But not all of them require
an upfront authentication. So here is the
demo app we've been building in the past
couple of videos about Firebase authentication. In all of the past videos,
we've asked the user to sign in before they can
even start using the app to track their favorite number. And that makes sense if
you want to use their user ID as a key for data
store in the back end. Our app will hopefully
be used by thousands of users who want to track
their favorite number. And we need a key to identify
which favorite number belongs to which user. But I am here today to tell
you that we don't actually need to ask our users to
create an account before they can start using the app. So in this specific
version of the app, the user can start using the
app without first signing in. And still, all of that data will
be stored in Cloud Firestore, using a unique key which helps
the app tell my data apart from your data. What's more, when the
user really likes the app they can then sign
in, which gives them a number of benefits. For example, they can sign
into the app on another device to access the same data. To make this work, I've
implemented anonymous auth and account linking in the app. Anonymous auth allows users
to start using the app without having to sign in. You can think of this
as guest accounts. Account linking,
on the other hand, allows your users to
sign into your app with multiple
authentication providers. For example, a user might
sign into your app with email and password first
but later decide they would rather sign
in using Google sign-in or sign in with Apple. Account linking
allows you to connect different authentication
credentials and roll them into a
single user account. Bringing anonymous
auth and account linking together
like this allows us to implement a smooth
onboarding flow like the one I just showed you. Let's first implement
anonymous auth in our app. If you want to follow
along, you will find the starter app in
the GitHub repository for this video. The link is in the
description below. All right. So anonymous authentication is
one of the many authentication mechanisms that Firebase
R provides out of the box. When a user of your app
uses a feature of your app that requires authentication,
called auth.signinanonymously to sign them in
anonymously, this will create a new Firebase
user with a user ID that is unique to your project. But other than a user who
signed in using, say, email and password
authentication or signed in with Apple, an
anonymous user doesn't have any personally identifiable
information on them. Their UID is completely
random and not connected to the person's
identity or the identity of their device in any way. You can use the UID
as a key for any data that you want to
store for this user. In our sample app,
we want to let users store their favorite
number in the cloud. So we need to add a user ID
property to the Firestore document that we use
to store this data. Depending on the use
case of your app, you might store
other kinds of data. For example, your app might
be a photo-sharing app. And you might be
using cloud storage to store your users photos. You can use the
user's UID as part of the path to all
their photo files and store all of the user's
photos in the same folder. To allow users to start
using your app without having to create a new-user account,
call it sign-in anonymously as early as possible in
the lifecycle of your app. But first, it's a good idea
to check if there already is a logged-in user. This will be the case if
the app was launched before. In this case, there would
be an anonymous user who is already signed in. Or the user signed in using
one of the other authentication providers. Either way, if there
already is a user account, we don't need to sign
in anonymously again. But if the current user property
is nil, no user has signed in. And we should call
sign in anonymously to create an anonymous account. Since this is an
asynchronous call, we will have to call
it using a wait. Doing so will suspend
the current function. This makes sure the
application doesn't freeze while we're waiting for
the result of this operation. And if the call succeeds, the
user is signed in anonymously. And in case the call
throws an error, we will assign the error message
to the error message property on the view model to let the
user know something went wrong. Now, you might be
wondering why we don't use the result of this call. The reason is that
we have registered an authentication
state listener which will react to any
authentication state changes. So whenever a user signs into
our app or signs out again, this piece of code
up here will be run. This allows us to centralize any
code that updates the UI state, based on whether a
user is signed in. Using anonymous
authentication is the first step to implementing
a smooth onboarding experience. But there is more. Users might want
to be able to use the app on their other devices
or share some of their data with friends and family. For both of these
use cases, we need to be able to refer
to the user's data by using their user ID. And that means we need
to be able to have a human-readable
handle that we can use to refer to this account. This will require upgrading
their anonymous account to a permanent account. To achieve this,
the user will have to authenticate using another
authentication mechanism. For example, Google sign
in, sign in with Apple, or any other of the
authentication providers supported by Firebase
authentication. Once a user has
successfully authenticated using one of these providers,
we can link their credentials to the existing
anonymous account. Upgrading an anonymous
account to a permanent account in this way ensures that
all of the user's data will still be
accessible to them. This works because
the upgraded account will keep the UID of
the anonymous account. Let's see how we can implement
this in our sample app. A good place to
upgrade the currently signed-in anonymous account
to a permanent account is the sign-up screen. When the user uses one of
the authentication mechanisms provided by the
screen, we will then use the resulting
credentials and link them to the anonymous account. Let's implement this for email
and password authentication. First, we will use the
email auth provider to create an auth
credential for the email and password the user
typed into the signup form. We will then check
if there actually is a currently signed-in user. If there isn't, something is
seriously wrong with our app. And we will throw a fatal error. We'll then call the link
with credential function on the anonymous user to
link this email and password credential to the
anonymous user. This will effectively
upgrade the anonymous user to a permanent user
account that can now sign in using the email and
password credential provided by the user. Since the authentication
state of the logged-in user didn't change-- they are still signed in, after
all-- the authentication state listener will not be triggered. This means we will have to
extract the updated user account from the
result of this call and assign it to the user
property on the view model. And, finally, we will
return true to let the caller know that linking
the account succeeded. Let's run the
application one more time to see the result of
our work in action. First, reset the
simulator to make sure we've got a clean
slate and to prove that we are running the
application for the very first time. Once the application
has launched, we see the main
screen with the picker for the user's favorite number. At the bottom of the
screen we see that we're using the app as guest user. I've refreshed the list of
users in the Firebase console. And we can see that there is an
anonymous user with this UID. I'll change the
favorite number to 17. And a quick look at
Firestore shows us that there is a Firestore
document with this number. And its user ID field contains
the UID of the anonymous user that's signed into the app. I will tap in on the Login
button to open the login view. To link the anonymous
account to an email address, I flip over to the
signup page and enter the email address of the
user I want to sign in as and pick a password. When I tap on sign up, the
app links these credentials to the anonymous account and
dismisses the signup form. Back on the main
screen, we can see that we're now signed in
using this email address. Let's take a quick look
at the profile view to see more details about
the signed-in user account. Since this account is now
linked to the email address I provided when signing
in, it no longer is an anonymous account. And, consequently, it's not
a guest account anymore. Let's double check
this by looking at the Firebase console. And, sure enough, we can see
that the user with this UID, which used to be an
anonymous account, now has an email address
as its identifier. And the only authentication
provider linked to it is the email
authentication provider. To demonstrate that the
data stored in Firestore can now be accessed from
any of the user's devices, I will launch the same
app on a second simulator. Again, this is a fresh
simulator so the app hasn't been run on this device before. Once the app launches,
we're assigned as a different anonymous user. Let's open the login form and
sign in using the email address and password we just used. Once I hit log-in we are signed
in as FredFirebase@gmail.com on both devices. And we can see Fred's favorite
number on both devices. Any changes I make
on one of the devices will be reflected on the
other one and vice versa. Great. You just saw how to
use account linking to upgrade an anonymous
user to a permanent user. But account linking also
works in other scenarios. For example, when
a user first signs in using email and
password authentication but would then like to sign
in using a federated identity provider like Google sign
in or a sign in with Apple, you can use the same approach. You first need to
make sure the user has signed in using their original
authentication mechanism. Then you ask them
to authenticate using one of the other
authentication providers you support in your app, and
link the credentials returned from the provider to
the existing account. For more details
about this, check out the documentation,
specifically the section about verified email addresses. So there you have it. We've optimized the onboarding
experience for our users by using anonymous auth
and account linking. Removing the need to
sign in or create a user account before being
able to use the app reduces friction and makes it
much more likely that people will actually use your app. So the next time you implement
authentication in your app, consider using this approach. As always, the source
for the sample app is available on our
GitHub repository. And the link is in
the description below. If you've got any questions,
leave them in the comments below or hit me up
on social media. I am @PeterFriese on Twitter
and @PeterFriese@iosdev.space on Mastodon. Stay safe and I will
see you in the next one. [AUDIO LOGO]