<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Sandra</title>
    <description>The latest articles on DEV Community by Sandra (@sandrantsoele).</description>
    <link>https://dev.to/sandrantsoele</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F875387%2Fad76a187-8550-437b-a775-8fb198f7fc18.jpeg</url>
      <title>DEV Community: Sandra</title>
      <link>https://dev.to/sandrantsoele</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sandrantsoele"/>
    <language>en</language>
    <item>
      <title>Firebase Auth with Supabase</title>
      <dc:creator>Sandra</dc:creator>
      <pubDate>Wed, 27 Jul 2022 14:00:00 +0000</pubDate>
      <link>https://dev.to/sandrantsoele/firebase-auth-with-supabase-ka6</link>
      <guid>https://dev.to/sandrantsoele/firebase-auth-with-supabase-ka6</guid>
      <description>&lt;p&gt;This is a quick guide to using Supabase's Row Level Security with &lt;strong&gt;Firebase Auth on Flutter&lt;/strong&gt; without having to write any additional middleware.&lt;/p&gt;

&lt;p&gt;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...&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Create a table in Supabase
&lt;/h2&gt;

&lt;p&gt;Assuming that you already have a project in Supabase, create a &lt;em&gt;users&lt;/em&gt; table and enable RLS in the process using the code below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE TABLE users (
    user_id VARCHAR(250) PRIMARY KEY,
    email VARCHAR(250) NOT NULL
);

ALTER TABLE users ENABLE ROW POLICY;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2: Create a validator function
&lt;/h2&gt;

&lt;p&gt;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:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE OR REPLACE FUNCTION email_verified() 
RETURNS boolean LANGUAGE sql stable AS
$$
SELECT NULLIF(
current_setting('request.jwt.claims', true)::json -&amp;gt;&amp;gt; 'email_verified', 'false'
)::boolean;
$$;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3: Enable RLS policies
&lt;/h2&gt;

&lt;p&gt;Using the policy creation dialog here's the code to use for the CHECK expression.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;NB: For INSERT queries it's important that you also have a SELECT policy in place. Otherwise your requests will fail&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;email_verified() = true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn3rslnrcj2cvx4iz57e5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn3rslnrcj2cvx4iz57e5.png" alt="INSERT policy"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Override the default JWT
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Create a supabase JWT
&lt;/h3&gt;

&lt;p&gt;To do this you will need the:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Firebase JWT,&lt;/li&gt;
&lt;li&gt;Your Supabase JWT secret,&lt;/li&gt;
&lt;li&gt;The &lt;a href="https://pub.dev/packages/dart_jsonwebtoken" rel="noopener noreferrer"&gt;dart_jsonwebtoken&lt;/a&gt; library and&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://pub.dev/packages/jwt_decoder" rel="noopener noreferrer"&gt;jwt_decoder&lt;/a&gt; library&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Below is the code for creating a supabase token&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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]"));
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Call setAuth from the Supabase client
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Supabase.instance.client.auth.setAuth(accessToken());
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s all! &lt;/p&gt;

&lt;p&gt;You have now successfully connected FirebaseAuth to Supabase whilst keeping things secure.&lt;/p&gt;

&lt;p&gt;There are certain things that I do not cover in here for the purposes of brevity. Things such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Synchronising users between the two systems&lt;/li&gt;
&lt;li&gt;Verifying user emails in FirebaseAuth&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But these and probably more are important to think about when using this approach.&lt;/p&gt;

&lt;p&gt;🚀 &lt;/p&gt;

</description>
      <category>firebase</category>
      <category>supabase</category>
      <category>flutter</category>
      <category>dart</category>
    </item>
  </channel>
</rss>
