What is the process for updating information once the user has verified their email address on Supabase using Next.js

After a user signs up using a magic link, I want to update the profiles table in my database. Below is the code snippet I am currently using:

Login.tsx

import { useState } from "react";
import { supabase } from "../lib/initSupabase";

const Login: React.FC = () => {
  const [email, setEmail] = useState<string>("");

    async function updateProfile() { // issue here
      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;

When users click the "Send magic link" button, they receive an email as expected. However, the table does not get updated.

Example showing the working updateProfile() function

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;

You can also find the complete code on GitHub: https://github.com/codewithanish/cwe-test

Answer №1

To update the table in supabase, avoid directly editing it and use the following method instead:

const { user , error } = await supabase.auth.update({email: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="26494c4e674d59444d19445940240c484549">[email protected]</a>'})

Answer №2

If you need to verify email sessions, you can follow these steps:

Click here for documentation

If "Email Confirmations" is enabled, a user will be returned but the session will be null
If "Email Confirmations" is disabled, both a user and a session will be returned

For an example of profile updates in NextJS, check out this nextJS example:

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)
    }
  }

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the more efficient approach: retrieving all data in one request or making individual requests for each piece?

When it comes to performance, which method is more efficient: 1) Retrieving 100 records in a single fetch request 2) Fetching each data row individually (100 times) P.S. I am using the axios library ...

Using NestJS to pass request and response parameters

I have a function in my services set up like this: ` @Injectable() export class AppService { getVerifyToken(req: Request, res: Response) { try { let accessToken = process.env.ACCES_TOKEN_FB; let token = req.query["hub.verify_t ...

The error encountered is: "Unable to modify the 'x' property as it is readonly for the '[object Array]' object."

I've attempted various methods to modify this problem, regardless of how it's explained on different Stack Overflow threads. I am faced with an obstacle where I have an array composed of objects, and my goal is to iterate through the array and mo ...

leveraging third party plugins to implement callbacks in TypeScript

When working with ajax calls in typical javascript, I have been using a specific pattern: myFunction() { var self = this; $.ajax({ // other options like url and stuff success: function () { self.someParsingFunction } } } In addition t ...

I encountered an error stating "Buffer is not defined" originating from the Deode/Encode Stream Bundle.js script, not from my own code

I've encountered a major issue while attempting to update my npm project to webpack 5, and now I'm left with just one persistent error: bundle.js:1088566 Uncaught ReferenceError: Buffer is not defined at bundle.js:1044980:24 ...

Is there a way to display two words side by side in React components?

I previously had the following code: projectName: project.get('name') === 'default' ? 'No Project' : project.get('name') In the render() method, it was written like this: <div className='c-card__projects&ap ...

Set up an event listener for when geolocation permission is approved

My Setup: I've written some basic code snippet below: const onSuccess = () => { console.log('success'); } const onError = () => { console.log('error'); } navigator.geolocation.getCurrentPosition(onSuccess, onError) ...

Unusual shift in the modal's behavior occurs when the parent component's style.transform is applied

I have encountered an unusual issue with a modal's appearance and functionality. The modal is designed to enlarge images sent in a chat, with the chat upload preview div serving as the parent element and the modal as the child element. This strange be ...

Facebook Debugger unable to detect the following OG Image

I've successfully set up the NextJs OG Image, and everything seems to be working fine. However, Facebook is unable to infer the image even though all other aspects are functioning properly. The specific error/warning message states: The 'og:image ...

Tips on extracting value from a pending promise in a mongoose model when using model.findOne()

I am facing an issue: I am unable to resolve a promise when needed. The queries are executed correctly with this code snippet. I am using NestJs for this project and need it to return a user object. Here is what I have tried so far: private async findUserB ...

When implementing `redux-observable` with NextJS, the `HYDRATION` action may not properly receive the server payload

Packages: redux-observable@2.0.0-rc.2 rxjs latest universal-rxjs-ajax dev branch next-redux-wrapper latest next.js latest I am working on a simple Page with getStaticProps: export const getStaticProps = wrapper.getStaticProps((store) => async (ctx) =& ...

Frontend Axios request fails to retrieve necessary data from MongoDB backend database

Reaching out to the backend to retrieve posts from a mongoDB database. Successful in postman but encountering a custom error on the frontend. Puzzled as to why it's not functioning properly. Utilizing Redux to fetch user information for ...

After being deployed on Vercel, React is mistakenly redirecting to the incorrect file, although it functions properly when

I'm a beginner in JavaScript and I recently created a React project. Everything was working smoothly in local development until I deployed the project on Vercel. The issue is when a user clicks on the "about button," instead of showing 'about.htm ...

Retrieve the response status using a promise

There is a promise in my code that sometimes results in an error response (either 400 or 403, depending on the user). I am trying to handle this situation by catching the response and implementing a conditional logic to execute different functions based on ...

Exploring the concept of rest arrays within a destructured object

Is there a way to declare c as an optional array of any type in this code snippet? const a = ({ b, ...c }: { b: string, c: ? }) => null ...

When converting Next.js build to HTML, useEffect code does not run

While working on my Next app router to create a static site, I encountered an issue with the 'client' component. The component uses useEffect to render KaTeX equations, but after running npm run build, the component does not display the content. ...

Developing a personalized Hook with useRef functionality

Here is a code snippet where I demonstrate creating two custom hooks in React. The first hook, `useChangeText`, utilizes the `useState` hook and works as expected. The second hook, `useGetHTML`, attempts to use `useRef` to log an HTML element to the cons ...

Implementing canActivate guard across all routes: A step-by-step guide

I currently have an Angular2 active guard in place to handle redirection to the login page if the user is not logged in: import { Injectable } from "@angular/core"; import { CanActivate , ActivatedRouteSnapshot, RouterStateSnapshot, Router} from ...

Struggling to connect the array of objects from the .ts file with the template (.html) in Angular

Inside this .ts file, I am populating the "mesMenus" array that I want to display in the .html file: export class MenusComponent{ mesMenus= new Array<Menu>(); constructor(private gMenuService:GestionMenuService){ this.gMenuService.onAdd ...

Activating a function on a click or item selection in React using Office UI Fabric's

<div> <CommandBar areNamesVisible={false} areIconsVisible={true} items={[ { name:"James Towns", className:"noHoverEffect", }, { key:"Info", icon:"Contact", onItemClick={this.handlePanel} ...