This is a quick guide to using Supabase's Row Level Security with Firebase Auth on Flutter without having to write any additional middleware.
Supabase officially supports many authentication providers, including SuperTokens, AuthO, and others. However, there is currently nothing for Firebase, but to be fair, I'm not sure of many use cases like this, so perhaps that's why it doesn't exist...
I was stuck for a few days trying to figure this out. So it seems only fair to share what I've come up with as a solution for others to find - especially since I noticed a couple of questions.
Step 1: Create a table in Supabase
Assuming that you already have a project in Supabase, create a users table and enable RLS in the process using the code below.
CREATE TABLE users (
user_id VARCHAR(250) PRIMARY KEY,
email VARCHAR(250) NOT NULL
);
ALTER TABLE users ENABLE ROW POLICY;
Step 2: Create a validator function
You can use any of the keys in the JWT payload to verify a user, but for this guide, I'll use the "email verified" key. The following is the code:
CREATE OR REPLACE FUNCTION email_verified()
RETURNS boolean LANGUAGE sql stable AS
$$
SELECT NULLIF(
current_setting('request.jwt.claims', true)::json ->> 'email_verified', 'false'
)::boolean;
$$;
Step 3: Enable RLS policies
Using the policy creation dialog here's the code to use for the CHECK expression.
NB: For INSERT queries it's important that you also have a SELECT policy in place. Otherwise your requests will fail
email_verified() = true
Step 4: Override the default JWT
Create a supabase JWT
To do this you will need the:
- The Firebase JWT,
- Your Supabase JWT secret,
- The dart_jsonwebtoken library and
- jwt_decoder library
Below is the code for creating a supabase token
accessToken() async
{
// GET JWT from Firebase
String firebaseToken = await FirebaseAuth.instance.currentUser!.getIdToken();
// Decode JWT to extract payload
Map payload = JwtDecoder.decode(firebaseToken);
return JWT(payload).sign(SecretKey("[SUPABASE JWT SECRET]"));
}
Call setAuth from the Supabase client
Supabase.instance.client.auth.setAuth(accessToken());
Thatβs all!
You have now successfully connected FirebaseAuth to Supabase whilst keeping things secure.
There are certain things that I do not cover in here for the purposes of brevity. Things such as:
- Synchronising users between the two systems
- Verifying user emails in FirebaseAuth
But these and probably more are important to think about when using this approach.
π
Top comments (0)