How To Verify A Users Photo ID In (Complete Guide)

In this guide, I’ll teach you how to build your own user verification system without writing a single line of code in Bubble. Now, why would you need to build a feature like this? If you’re creating your own on-demand service like Uber or DoorDash, you might want to be able to verify third-party contractors before they start using your app. Because of course, once you can verify someone, that’s going to create a much safer experience for your own users.

Now, in today’s real-world example, when a contractor signs up to my ride-hailing app, I’m going to have them also upload a copy of their ID, from which, I’m then going to create an admin dashboard so that I can review that application and choose whether or not I want to either approve or deny their verification.

And of course, like anything in Bubble, I always like to take things that one step further. That’s why today, we’re also going to create a way to restrict certain features in our application to only those users who have been approved, so that way we don’t have any old user getting access to important information that only our delivery drivers should see. Look, at this point, I’ve already said enough. There’s so much that I want to cover, so let’s just grab our Bubble editor and we can dive right into it.

The steps to creating a user verification feature in Bubble include:

  1. Setting up your custom database
  2. Designing a sign-up page
  3. Building the workflow to approve a user
  4. Building the workflow to reject a user
  5. Excluding features to only approved users

Full Transcript of Tutorial

Throughout our tutorial today, there’s quite a few steps involved in the process of creating our own verification feature. Now, as I mentioned, today we’re going to be building out a feature similar to something like an Uber or a DoorDash, where we have an on-demand service that requires people to sign up as delivery drivers. 

Before these users are allowed to actually start working on our platform, we as the admins will need to verify their registration and their license. It’s at this point that we can either approve or reject each user. But before we build anything out in our app, the first thing I just want to do is show you the database setup that I would encourage if you want to build a verification feature.

1. Setting up your custom database

I’m going to open up a Bubble editor that I’ve created for the sake of this guide. Within this editor, the first thing I want to do is just open up my data tab and show you how I’ve set up my user data type. 

Every single time someone creates an account within my app, there’s a series of data fields I’d like to store for each user, and the very first field is the account type for this person. So is this user a delivery driver, or someone that’s ordering food?

Now, for the sake of this tutorial today, I’ve set this just as a text field. This means that whenever someone registers an account, I’m going to store a particular value for what type of person they are on our platform. 

Now, if you really wanted, you could use option sets for this as well. This would allow users to select from a list of pre-vetted options. For the sake of our tutorial, however, I wanted to keep things as basic, as possible. I don’t want you to have to go down the rabbit hole of trying to learn what option sets are if you’re brand new to Bubble.

Below this, I then have another field which is known as the approved status. Now, this field has been set to a ‘yes/no’ value because someone will either be approved or won’t be approved. 

What I’ve also done is I’ve set a default value for this field to be ‘no’. This means that when a user registers an account as a delivery driver, by default, their approved status will be ‘no’. This driver will only be approved once we say so. Of course, later on, we’ll be building out a dashboard that allows us to review all of our requested drivers, from which we can then choose to either approve or reject them.

I then also have a data field for a user’s license. Now, this is just going to be an image field type. When someone registers an account, they’ll have the ability to take a picture of their license and upload it into our database. 

Following on, we then have fields that store a users name, their profile photo, and their registration number. Now, I’ve set the value of our registration number field to be text type because this allows us to include both text and numbers.

Finally, the last data field I created is known as my ‘rejected status’. Whenever a driver signs up for an account, as I mentioned before, the default value for their approved status will be set to ‘no’, but we’re also going to need to create a way to identify all of the users that we’ve actually rejected. 

If we were to just say that we didn’t want to approve a driver, there wouldn’t be a way to determine if they’re currently a new, pending account, or if they’ve been rejected. This new data field will allow us to determine which users we’ve actually turned away.

When it comes to this ‘rejected’ data field, I’ve once again set the type of data to be a ‘yes/no’ field with a default value of ‘no’.

Now, that is how I’ve set up my own custom database, but by all means, if you want to store more information about your users or your drivers, feel free to add as many data fields as you’d like. But just at the bare minimum for my example today, this is all of the information I’ll need to store about a user.

2. Designing the signup page

After building out our database, I’ll then want to open our design tab to review the existing user sign-up page I’ve already created. 

On this page, I’ve added a series of input fields that allow me to register a users name, profile photo, email, password, registration number, as well as their photo ID.

Now, although I’ve already jumped ahead and I’ve built out this page, I do just want to walk you through the workflow steps involved in signing someone up.

If I click on my register button, it’ll open up my workflow tab. Within this workflow, what I’d like to do is head to our ‘account’ events and select the ‘sign the user up’ action. Of course, if you’ve ever signed someone up for your application in Bubble, you’ll know that they’ll need an email and a password by default. To store this data, I’ll match the value of this user’s email to be the value that I’ve added to our input email field. Then, for the password, this is going to be the exact same thing.

Now, what I’d also like to do is update some additional data fields for this user. So, the first thing I’d like to do is store an account type for this user. I’m just going to remove the option to add in dynamic data and I’m just going to type this in as the word driver. 

One thing I will point out, though, is how I’ve spelled the word ‘Driver’ here. In this instance, I’ve capitalized the word with a capital D. I’ll just need to remember that for future reference. 

The next field I’d like to update is going to be the user’s license. I should just point out that I won’t need to update the user’s approved status at this point because if you remember, the user’s approved status is set to no by default. This means that it’s already been taken care of.

For the users license, I’m going to store this as an image. 

I’m then going to jump ahead and store the user’s name, which is of course, the value of the ‘input name’ on my page.

Then there was the users profile photo, as well as their registration number. I’ll also be matching these values with the relevant fields on our sign-up page.

One thing I just wanted to highlight throughout this process is that I don’t need to update the user’s rejected status. By default, that value has been set to ‘no’. The main reason why I just wanted to show you how I built out this workflow is not for these fields here, but it’s more so just around adding a type of account for this person. Because this is a dedicated page that allows drivers to sign up to my platform, I know that I can mark anyone who signs up through this form as a driver in my database.

Now, let’s just say after this step in our workflow runs, I just like to redirect someone through to a page. What I’m going to do is just select from a navigation event, choose the ‘go to page’ action, and I can send them to whatever page I want. I’m just going to send them to my index page, which has nothing on it. 

Once a driver has registered an account within my app, what I’d like to do is create a dashboard for the admin of this application. This dashboard would allow them to review a list of all of the drivers who have signed up for an account and are yet to be approved.

What I’m going to do is open up a page that I have prebuilt. This page is known as my approval dashboard. Now, there’s not much on this page, but I just wanted to give you a quick rundown of how I’ve set this up. 

On our approval dashboard, as an admin, what I’d like to do is view a list of all of the drivers who are currently awaiting to be approved. What I’ve done is I’ve added a repeating group onto this page here and this repeating group is just displaying a list of users. If I open up my data source, I just want to run you through what particular users I’m going to be searching for in my database.

The first thing I should point out is that when it comes to the users you want to display, you only want to display those users where the account type is a ‘driver’. You’re not going to want to display those users who are just consumers. 

Then, I’m going to add two additional constraints. One will only display users where the approved status equals ‘no’. So these are the people who have not yet been approved in their application. If you remember, when someone signed up for an account, by default their approved status was set to ‘no’. This means that they will automatically be displayed here.

But let’s say a user has been rejected. Their approved status would still sit as ‘no’. In this instance, we don’t want to continually display this person in this list as we’ve already made our decision about this person. 

In order to remove that user from the list, I’ve also added a constraint that only displays users where the rejected status also equals ‘no’. If the rejected status was to equal ‘yes’, I wouldn’t want to display that person in this list anymore.

And that’s everything I’ve added to the data source of my repeating group. Inside of my repeating group, I’ve just added three elements. One is just displaying the profile photo of this person. The other is just displaying their name, then finally, I have a button that will display a popup when clicked. Within this popup, it will show all of a user’s information. This information includes data like their drivers license and registration number.

When it comes to this popup, I’ve set a type of data on the element to be a ‘user’. This will allow me to store the value of an individual person within the popup each time it’s opened.

Now, one thing I should also point out is how I’ve built out the workflow to display this pop-up. Whenever this ‘view details’ button is clicked here, my workflow will send data from our repeating group through to the popup element. 

Then from here, my workflow will just show an element. That element is of course our popup. 

At this point, one of the last things I want to show you is how we can, of course, build out the workflows to approve or reject a particular driver.

3. Building the workflow to approve a user

Back on my dashboard page, you’ll see within my popup that I have two buttons at the bottom of the group. One button will be used to approve users, while the other will be used to reject them.

At this point, what we’ll need to do is create workflows that run when each button is clicked. I’m going to start by creating the workflow that runs whenever the ‘approve’ button is clicked.

Within this workflow. the first thing I’d like to do is just make changes to the person whose profile we’re viewing. In which case, I’m going to want to update their approved status from ‘no’ to now equal ‘yes’.

If I selected from the data tab, I’m going to choose to ‘make changes to a thing’. The thing I’d like to make changes to is the ‘current group user’. So, if you remember, once again, I’m storing the data of someone within my pop-up. This means that whoever is being displayed in my pop-up, I’m going to make changes to their account. The field I’d like to make the changes to is going to be the approved status. In this case, I’d now, like to set this as ‘yes’. It truly is as simple as that. That’s all I’m going to need to change.

Then finally, what I’d like to do is add an additional step in my workflow that’s then going to hide my pop-up. So if I head to my element actions, I’m going to choose to hide an element. The element will, of course, be the pop-up that we’re viewing. Now, because we’re creating a feature to approve someone, what I’d love to do is add a color to this workflow so I can easily differentiate where it sits in my actual workflow. I’ll be setting the color of this workflow trigger to green.

Now one thing I should mention is that once the users approved status has been set to ‘yes’, they’ll no longer appear in our repeating group. If you remember, we’re only performing a search for users where the approved status is ‘no’. This means that it’ll automatically remove someone from that list once this value is changed.

4. Building the workflow to reject a user

Now, the last thing we’ll need to do is build out the workflow to reject a user. I’m going to open up my pop-up and select the ‘reject’ button. I’ll choose to start a workflow whenever this is clicked. This workflow will be very much the same as our previous workflow, so I’ll select our data tab, then choose to ‘make changes to a thing’.

The thing I’d like to change is once again, going to be the ‘parent group’s user’. This is the user being displayed in my pop-up. The one field I’d like to change here is going to be the rejected status. Instead of this status being set to ‘no’ by default in our database, I’d now like to update this to ‘yes’. This means we have said that we don’t want to approve this user. 

The last thing I’d like to do in this workflow though, is add that additional step to hide my pop-up. So, I’m going to head to my element actions once again, choose to hide an element and the element will be in my pop-up. And now, because this is the workflow where we’re rejecting a user, I’m going to select on the workflow trigger and I’ll update the color of this to be red.

5. Excluding features from rejected users

Let’s say you’ve got a page in your application that you only want approved drivers to be able to see. What you can do is create a condition on any element that allows you to exclude unapproved drivers from getting access to content.

If we jump back into our Bubble editor, I’m going to open up another page I’ve created called my ‘driver dashboard’. In a real-world app, this page would contain a list of all the incoming deliveries a driver could accept.

On this page, you’d only want users who are approved drivers to have access to this content. 

If you wanted to restrict this page to only your approved drivers, you could create a workflow that runs every single time the page is loaded. Within this workflow, you could verify if the user is a pre-vetted driver. Of course, if they’re not, we could easily redirect them back to our home page.

This feature would insure that any sensitive data would only be visible to the users we choose.

To build this out, we’ll need to create a new workflow from scratch on this page. This workflow will be triggered ‘each time the page is loaded’. 

On the trigger for this workflow, I’ll add a condition that recognizes if the current users approval status is currently ‘yes’.

Within the workflow action itself, I’d like to redirect someone away from this page, so what I’ll do is select the ‘go to page action. In this instance, I’ll send someone back to our home page.

And just like that, you now have a way to exclude rejected users from getting access to certain pages within your app. Of course, if you’d ever like to hide select elements from these users, you could replicate the same condition from our workflow trigger to any element within your app. You could also choose to hide elements from users whose approved status isn’t currently ‘yes’.

At this point in time, you’d have a fully-functional user verification system within your Bubble app. Of course, all of this was created without having to write a single line of code.

Never miss a course 👇