I would like to update my profiles table once my user signs up with a magic link.
Here is my current code:
Login.tsx
import { useState } from "react";
import { supabase } from "../lib/initSupabase";
const Login: React.FC = () => {
const [email, setEmail] = useState<string>("");
async function updateProfile() { // this doesn't work
try {
const user = supabase.auth.user();
const updates = {
id: user?.id,
username: email,
updated_at: new Date(),
pricing_plan: "free",
};
let { error } = await supabase.from("profiles").upsert(updates);
if (error) throw error;
} catch (error: any) {
alert(error.message);
}
}
// login function
const handleLogin = async (email: string) => {
try {
// sign in with email
const { error } = await supabase.auth.signIn({ email });
if (error) throw error;
alert("Check your email for a link to log in.");
updateProfile();
} catch (error: any) {
alert(error.error_description || error.message);
}
};
return (
<div className="container mx-auto grid place-content-center h-96">
<p className="mb-4">Sign in via magic link with your email below</p>
<input
className="mb-4 border-2 border-gray-500 rounded-xl p-4 w-full"
type="email"
placeholder="Your email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
<button
onClick={(e) => {
e.preventDefault();
handleLogin(email);
}}
className="w-full mt-4 p-2 pl-5 pr-5 bg-blue-500 text-gray-100 text-lg rounded-lg focus:border-4 border-blue-300"
>
<span>Send magic link</span>
</button>
</div>
);
};
export default Login;
Currently when a user clicks the "Sign magic link" button. They receive an email (as expected). However, my table isn't updating.
Example of updateProfile() function working
import { Session } from "@supabase/supabase-js";
import { useState } from "react";
import { supabase } from "../lib/initSupabase";
interface Props {
session: Session | null;
}
const Profile: React.FC<Props> = ({ session }: Props) => {
const [username, setUsername] = useState<
string | number | readonly string[] | undefined
>("");
async function getProfile() {
try {
const user = supabase.auth.user();
let { data, error, status } = await supabase
.from("profiles")
.select(`username`)
.eq("id", user?.id)
.single();
if (error && status !== 406) {
throw error;
}
if (data) {
setUsername(data.username);
}
} catch (error: any) {
alert(error.message);
}
}
async function updateProfile() {
try {
const user = supabase.auth.user();
const updates = {
id: user?.id,
username,
updated_at: new Date(),
};
let { error } = await supabase.from("profiles").upsert(updates);
if (error) throw error;
} catch (error: any) {
alert(error.message);
}
}
return (
<div className="container mx-auto grid place-content-center h-96">
<p>Oh hi there {session?.user?.email}</p>
<input
className="my-4 border-2 border-gray-500 rounded-xl p-4 w-full"
type="username"
placeholder="Enter a username"
value={username}
onChange={(e) => setUsername(e.target.value)}
/>
<button
onClick={(e) => {
e.preventDefault();
updateProfile();
}}
className="w-full mt-4 p-2 pl-5 pr-5 bg-blue-500 text-gray-100 text-lg rounded-lg focus:border-4 border-blue-300"
>
<span>Update profile</span>
</button>
<button
className="mt-4 p-2 pl-5 pr-5 bg-blue-500 text-gray-100 text-lg rounded-lg focus:border-4 border-blue-300"
onClick={() => supabase.auth.signOut()}
>
Logout
</button>
</div>
);
};
export default Profile;
I also have to whole code listed on GitHub: https://github.com/codewithanish/cwe-test
CodePudding user response:
You can check for the sessions if you are checking for email verification:
If "Email Confirmations" is turned on, a user is returned but the session will be null
If "Email Confirmations" is turned off, both a user and a session will be returned
You can also check this nextJS example for an example of how to update profiles:
async function updateProfile({ username, website, avatar_url }) {
try {
setLoading(true)
const user = supabase.auth.user()
const updates = {
id: user.id,
username,
website,
avatar_url,
updated_at: new Date(),
}
let { error } = await supabase.from('profiles').upsert(updates, {
returning: 'minimal', // Don't return the value after inserting
})
if (error) {
throw error
}
} catch (error) {
alert(error.message)
} finally {
setLoading(false)
}
}
CodePudding user response:
You are trying to directly edit the table, thats not how it works within supabase, you should be using this instead:
const { user, error } = await supabase.auth.update({email: '[email protected]'})