I have an app where people can sign up for user accounts. They can use their Google account or sign up using email/password. I am storing the user's displayName in Firestore so I can reference it throughout the app as their username.
However, there is a problem:
Let's say "John Doe" signs up for a user account on my app and he uses his Google account named [email protected]
. His Google account's display name is also "John Doe". However, a few days later, another with the same name "John Doe" signs up for a user account, and although his Google account email may be different (let's say, [email protected]
), his display name is still the same. Now, I have 2 users in my app with the same display name "John Doe". This causes an issue when I am trying to create user name routes such as: https://myapp.com/JohnDoe
and handling user profile lookups.
What is the recommended way to allow users to use their Google accounts if there are other users that may have the same display names? The catch is I don't want to store UIDs in the URL as I want it to be clean with just the displayName.
CodePudding user response:
It's quite common to see URLs suffixed with some random number or combination of alphanumeric characters like john-doe-1
and so on. That being said you would have to implement logic for this yourself maybe using Firebase Auth Triggers for Cloud Functions which will run whenever a new user is created and you can add an URL for their name.
You could also add some random string like /users/john-doe-qwerty
and maybe add a paid feature that allows user to set their own URLs (if applicable for your application) i.e. vanity URLs.
CodePudding user response:
The catch is I don't want to store UIDs in the URL as I want it to be clean with just the displayName.
It might be clean, as long as the number of characters within the displayName
is reasonable. In your example, "John Doe", contains only 8 characters, including the whitespace character between the names, which is fine. But I've seen so many examples of names that are larger than 28, the number of characters that exist in a UID. Since the displayName
property is set within the Google account and it can be changed only by the user, you're having three solutions left.
The first one would be to create your own mechanism for setting specific user names into your application. These user names can be set especially by the users. It can be the same as the names in the Google account or not. However, when someone chooses "JohnDoe" and a second user wants to set the same user name, it won't be possible, since a "JohnDoe" is already present. So before setting a new user name, you should always check if that one is already present. You can do that because it's something that you control. When using Firestore, this can be simply done by using:
db.collection("users").whereEqualTo("userName", "JohnDoe");
Or when using the Realtime Database:
db.child("users").orderByChild("userName").equalTo("JohnDoe");
Now, the first "John Doe" will have a profile that looks like this:
https://myapp.com/JohnDoe
While the second one might have something like this:
https://myapp.com/John_Doe
See the underscore? This kind of mechanism is very widely used. Facebook, Instagram, Twitter, eBay, Reddit, and many more do that:
https://www.facebook.com/JohnDoe/
https://www.instagram.com/JohnDoe/
https://twitter.com/JohnDoe/
https://www.ebay.com/usr/JohnDoe/
https://www.reddit.com/user/JohnDoe/
The second one would be to ignore the user names and use only the UIDs that come from the authentication process. Case in which, your URL will look like this:
https://myapp.com/TwentyEightCharactersLong
That's not unusual, since other big apps use it:
https://www.imdb.com/user/$userId/
The third one would be to create a combination between the UID and the user name. The best example would be Stackoverflow:
https://stackoverflow.com/users/$userId/$userName/
// ^ ^
Or LinkedIn:
https://www.linkedin.com/in/$userName-$userId/
// ^ ^
Doesn't matter which solution will you apply, you'll always have unique URLs. But it's up to you to choose which one of these solutions seems more clear to you.