One of the core basic functions, included in just about EVERY app I make, is the ability for the app to know WHO is using the app.
If the app knows who’s using it, then I can easily control many different aspects of the app:
- Add/edit/delete permissions
- How data should be filtered
- What views are shown
- What buttons, or Actions, are visible
- Which workflows should fire off
- Which columns should be shown or editable
- etc.
Requirements
To accomplish this functionality in your app, you need the following:
- A user table
- A column (in the User table) that holds the Email the user will use to access the app
- User sign in required
- A one-to-one match of records in the User table for each actual user of your app
The User Table
Details
Create a table for your app that will hold information specific to the user. This table must contain at least the following:
- A column to hold the Email of the person accessing the app
- An ID column, to uniquely identify that record out of the User table.
My rules for Table Keys
- Always a text column
- Always hidden
- Always UNIQUEID()
Your User table can contain any other information about the user you may need; for example:
- User_Role - to denote if someone’s an Admin, User, etc.
- User_Name - to hold their actual name (to display it in the app)
- User_Assigned_Accounts - a list of the accounts assigned to the user
- User_Hourly_Rate - the hourly rate of the user
- User_Icon - you get the idea…
User Sign-in Required
Why?
In order to restrict when certain things should be allowed or not, the app has to have some way of differentiating one user from another. While there is another way to accomplish this, requiring someone to sign in is the simplest of them all.
By requiring people to sign into the app before they can use it, you’re ensuring the when you use the function USEREMAIL() - there will be an email in response, and from this we can base permissions and such.
One-to-one match of User Records
Explanation
What I mean by this is that for each user accessing your app, you need to have a corresponding record in the User table for that user.
- For example: if Mary is accessing the app with the email Mary@email.com, then you’ll need to have a record in the User table for Mary with that email in the [User_Login_Email] column (or whatever you name that column).
If you do not have a record for the user, but you’re going to allow users to access the app anyways, then you need to conform your app around that eventuality - handling what happens when someone logs into the app but doesn’t have a User record.
Many of the techniques I’ll describe below (on how to use this system) depends on there only being a single record inside the User table for each user.
- If you have the possibility of users having multiple records in the same table (with the same login in email), then you’ll have to build in a system for the users to “flag” - or somehow otherwise denote - which record they want to use.
—| The Setup |—
-
Create a new slice of your User table
-
Inside the condition formula space, add something like this:
USEREMAIL() = [User_Login_Email]
-
(Optional) Remove the “Add” permissions from this slice (keep edit and delete, if you wish for users to able able to have those permissions for their User record)
How do I use this?
Now that you’ve got everything setup and put in place, you’re ready to actually pull information from the Current_User slice and use that in conditions throughout your app.
-
To pull a value
INDEX(Current_User[User_Role], 1)
ANY(Current_User[User_Name])
- though I suggest INDEX() in preference to ANY() -
To pull a list
SPLIT(Current_User[Related Timesheets], " , ")
SPLIT(Current_User[User_Assigned_Clients], " , ")
-
To restrict something for Admin role only
INDEX(Current_User[User_Role], 1) = "Admin"
-
To restrict something for Admin & Team Leader roles only
IN(INDEX(Current_User[User_Role], 1), list("Admin", "Team Leader"))
-
To see if a Client ID is inside the assigned client’s list for the user
IN([ClientID], SPLIT(Current_User[User_Assigned_Clients], " , "))
There are an endless amount of example formulas to give, but the one’s I’ve highlighted above provide instructions on how to handle both values and lists in some common scenarios.
Other Uses
This technique of isolating out a record in a slice can be very helpful when you want to conform the UX around a specific context or situation the user might be in.
- For example: you might create a slice to pull out newly created Timesheets, that lack a “close” time, by the user; this way you could easily create a “Time-clock” type of dashboard, or view, based on the presence of a record inside that Timesheet-isolating slice.