Alright, this is everything I set up:
A. Google Cloud Console
B. Supabase dashboard
- Enable Google under Providers
- Enter Client ID & Secret from the Google Cloud Console
- Under Auth > URL Configuration set your deep link url as Site URL, like so: com.nameapp.name://loginWithGoogle
- On the same page I added com.nameapp.name:// under Redirect URLs
C. Your app
- Link your login button to this function:
const loginWithGoogle = async () => {
const { data, error } = await supabase.auth.signInWithOAuth({
provider: "google",
options: {
queryParams: {
access_type: "offline",
prompt: "consent",
}
},
});
}
Btw, my Supabase client is just standard:
import { createClient } from '@supabase/supabase-js';
const supabaseUrl = 'https://yoururl.supabase.co';
const supabaseAnonKey = 'AnonKey';
const options = {
auth: {
autoRefreshToken: true,
persistSession: true,
detectSessionInUrl: true
}
}
export const supabase = createClient(supabaseUrl, supabaseAnonKey, options);
Next, Google will open your app using the set Supabase url, so that’s com.nameapp.name://loginWithGoogle#thestuffyouneedishere. There are multiple ways to ‘catch’ this, for the moment I have this working, will probably change/improve later but it works:
App.addListener("appUrlOpen", async (data) => {
console.log('opened app url');
console.log(data);
console.log('that happened');
const url = new URL(data.url);
const hashParams = new URLSearchParams(url.hash.substring(1)); // Remove the '#' at the start of the hash
const access_token = hashParams.get('access_token');
const refresh_token = hashParams.get('refresh_token');
const expires_in = hashParams.get('expires_in');
const token_type = hashParams.get('token_type');
if (access_token && refresh_token && expires_in && token_type) {
// Set the session
const { data: session, error } = await supabase.auth.setSession({
access_token,
refresh_token,
expires_in,
token_type
});
if (error) {
console.error('Error during setting session:', error);
} else {
console.log('Session:', session);
// Fetch and store the user data
const user = session.user;
await SecureStoragePlugin.set({ key: 'user', value: JSON.stringify(user) });
setCurrentUser(user);
}
}
});
}, []);
D. Android Deep Link
Last thing is that we have to set up our app to open our link (com.nameapp.name://loginWithGoogle). In AndroidManifest.xml I have:
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="com.nameapp.name" />
</intent-filter>
Now, I added similar things to config.capacitor.json, however I’m not sure which parts are necessary and I’m too lazy to figure out:
{
"appId": "com.nameapp.name",
"appName": "appName",
"webDir": "build",
"scheme": "com.nameapp.name",
"deepLinks": {
"scheme": "com.nameapp.name"
},
...
I also have CapacitorCookies and GoogleAuth enabled under plugins, again I’m not sure if this is necessary:
,
"plugins": {
"GoogleAuth": {
"scopes": ["profile", "email"],
"serverClientId": "yourClientID",
"forceCodeForRefreshToken" : true
},
"CapacitorCookies": {
"enabled": true
}
}
So… I believe that’s everything.