Building Real-time Apps with Supabase: A Step-by-Step Guide

In this tutorial, we will explore how to build real-time apps using Supabase. We will go through the process of setting up Supabase, building the user interface, handling real-time updates, implementing user authentication, integrating Supabase with other technologies such as React and GraphQL, and finally deploying the app to a hosting platform.

building real time apps supabase step step guide

Introduction

What is Supabase?

Supabase is an open-source Firebase alternative that provides a suite of tools to help developers build scalable and secure real-time applications. It combines the power of PostgreSQL and the simplicity of a RESTful API to provide a seamless experience for developers. With Supabase, you can easily add real-time functionality, user authentication, and authorization to your applications without the need for complex infrastructure or extensive backend development.

Why use Supabase for real-time apps?

Supabase offers several advantages for building real-time apps. Firstly, it leverages the power of PostgreSQL, a robust and reliable relational database system. This ensures that your data is stored securely and efficiently. Secondly, Supabase provides real-time functionality out of the box, allowing you to easily handle real-time updates to your application's data. Additionally, Supabase offers user authentication and authorization features, making it easy to add user management to your app.

Setting Up Supabase

Creating a Supabase project

To get started with Supabase, you will need to create a project. Go to the Supabase website and sign up for an account. Once you have logged in, you can create a new project by clicking on the "New Project" button. Give your project a name and choose a region for your database. Click on the "Create Project" button to create your project.

Configuring the database

After creating the project, you will be redirected to the project dashboard. Here, you can configure your database settings. Click on the "Database" tab and then click on the "Create Table" button to create a new table. Give your table a name and define the columns. You can also set constraints and data types for each column. Once you have configured your table, click on the "Create Table" button to create it.

Setting up authentication

Next, we need to set up authentication for our app. Click on the "Authentication" tab in the project dashboard. Here, you can configure various authentication providers such as email/password, Google, GitHub, etc. Choose the authentication provider(s) you want to enable for your app and follow the instructions to set them up.

Building the Real-time App

Creating the user interface

Now that we have set up Supabase, let's start building our real-time app. We will begin by creating the user interface using HTML, CSS, and JavaScript. Here's a basic example of a real-time chat app:

<!DOCTYPE html>
<html>
<head>
  <title>Real-time Chat App</title>
  <link rel="stylesheet" type="text/css" href="styles.css">
</head>
<body>
  <div id="chatbox"></div>
  <form id="message-form">
    <input type="text" id="message-input" placeholder="Enter your message">
    <button type="submit">Send</button>
  </form>

  <script src="app.js"></script>
</body>
</html>

In the above code, we have a simple HTML structure with a chatbox div, a form for sending messages, and a JavaScript file called app.js.

Handling real-time updates

To handle real-time updates in our app, we will use the Supabase Realtime feature. This feature allows us to subscribe to changes in our database and update our UI in real-time. Here's an example of how to handle real-time updates using Supabase Realtime and JavaScript:

import { createClient } from '@supabase/supabase-js';

const supabaseUrl = 'YOUR_SUPABASE_URL';
const supabaseKey = 'YOUR_SUPABASE_KEY';
const supabase = createClient(supabaseUrl, supabaseKey);

// Subscribe to changes in the messages table
const subscription = supabase
  .from('messages')
  .on('INSERT', (payload) => {
    // Handle new message
    const message = payload.new;
    appendMessage(message);
  })
  .subscribe();

// Function to append a new message to the chatbox
function appendMessage(message) {
  const chatbox = document.getElementById('chatbox');
  const messageElement = document.createElement('div');
  messageElement.innerText = message.content;
  chatbox.appendChild(messageElement);
}

// Unsubscribe from changes when the app is closed
window.addEventListener('beforeunload', () => {
  subscription.unsubscribe();
});

In the above code, we first import the createClient function from the @supabase/supabase-js package. We then create a Supabase client using our Supabase URL and key. Next, we subscribe to changes in the messages table using the from method and the on method with the 'INSERT' event. When a new message is inserted into the messages table, the callback function is called, and we append the new message to the chatbox.

Implementing user authentication

To implement user authentication in our app, we can use the Supabase Auth feature. This feature provides various methods for managing user authentication, such as signing up, logging in, and managing user sessions. Here's an example of how to implement user authentication using Supabase Auth and JavaScript:

import { createClient } from '@supabase/supabase-js';

const supabaseUrl = 'YOUR_SUPABASE_URL';
const supabaseKey = 'YOUR_SUPABASE_KEY';
const supabase = createClient(supabaseUrl, supabaseKey);

// Function to sign up a new user
async function signUp(email, password) {
  const { user, error } = await supabase.auth.signUp({
    email,
    password,
  });

  if (error) {
    console.error(error);
  } else {
    console.log('User signed up:', user);
  }
}

// Function to log in an existing user
async function logIn(email, password) {
  const { user, error } = await supabase.auth.signIn({
    email,
    password,
  });

  if (error) {
    console.error(error);
  } else {
    console.log('User logged in:', user);
  }
}

// Function to log out the current user
async function logOut() {
  const { error } = await supabase.auth.signOut();

  if (error) {
    console.error(error);
  } else {
    console.log('User logged out');
  }
}

In the above code, we import the createClient function from the @supabase/supabase-js package and create a Supabase client. We then define functions for signing up a new user, logging in an existing user, and logging out the current user. These functions use the supabase.auth.signUp, supabase.auth.signIn, and supabase.auth.signOut methods respectively to interact with the Supabase Auth API.

Integrating Supabase with Other Technologies

Using Supabase with React

If you are using React for your app, you can easily integrate Supabase using the @supabase/supabase-js package and React hooks. Here's an example of how to use Supabase with React:

import { createClient } from '@supabase/supabase-js';
import { useEffect, useState } from 'react';

const supabaseUrl = 'YOUR_SUPABASE_URL';
const supabaseKey = 'YOUR_SUPABASE_KEY';
const supabase = createClient(supabaseUrl, supabaseKey);

function App() {
  const [messages, setMessages] = useState([]);

  useEffect(() => {
    // Subscribe to changes in the messages table
    const subscription = supabase
      .from('messages')
      .on('INSERT', (payload) => {
        // Handle new message
        const message = payload.new;
        setMessages((prevMessages) => [...prevMessages, message]);
      })
      .subscribe();

    // Fetch initial messages
    fetchMessages();

    // Unsubscribe from changes when the component is unmounted
    return () => {
      subscription.unsubscribe();
    };
  }, []);

  async function fetchMessages() {
    const { data: messages, error } = await supabase.from('messages').select('*');

    if (error) {
      console.error(error);
    } else {
      setMessages(messages);
    }
  }

  return (
    <div>
      {messages.map((message) => (
        <div key={message.id}>{message.content}</div>
      ))}
    </div>
  );
}

export default App;

In the above code, we import the createClient function from the @supabase/supabase-js package and React hooks. We create a Supabase client and define a functional component called App. Inside the component, we use the useEffect hook to subscribe to changes in the messages table and fetch the initial messages. We also define a function to fetch messages from the database and update the messages state. Finally, we render the messages in the UI using the map method.

Integrating Supabase with GraphQL

If you prefer to use GraphQL for your app, you can integrate Supabase with GraphQL using tools like Apollo Client or Relay. Here's an example of how to integrate Supabase with GraphQL using Apollo Client:

import { ApolloClient, InMemoryCache, createHttpLink } from '@apollo/client';
import { setContext } from '@apollo/client/link/context';

const supabaseUrl = 'YOUR_SUPABASE_URL';
const supabaseKey = 'YOUR_SUPABASE_KEY';

const httpLink = createHttpLink({
  uri: `${supabaseUrl}/graphql`,
});

const authLink = setContext((_, { headers }) => {
  const session = JSON.parse(localStorage.getItem('supabase.auth.token'));

  return {
    headers: {
      ...headers,
      Authorization: `Bearer ${session.access_token}`,
    },
  };
});

const client = new ApolloClient({
  link: authLink.concat(httpLink),
  cache: new InMemoryCache(),
});

// Query example
client.query({
  query: gql`
    query {
      messages {
        id
        content
      }
    }
  `,
})
  .then((result) => console.log(result.data.messages))
  .catch((error) => console.error(error));

In the above code, we import the necessary packages from @apollo/client and create an Apollo Client instance. We also create an HTTP link using the Supabase URL and a context link to add the authorization header using the Supabase token stored in local storage. Finally, we use the Apollo Client instance to send a GraphQL query to fetch messages from the messages table.

Deploying the App

Preparing for deployment

Before deploying our app, we need to prepare it for production. This involves optimizing the code, bundling the assets, and configuring any necessary environment variables. Most modern frontend frameworks like React have built-in tools for preparing apps for production.

Deploying the app to a hosting platform

Once our app is ready for deployment, we can choose a hosting platform to host our app. There are several options available, such as Netlify, Vercel, and AWS Amplify. These platforms provide easy deployment workflows and often integrate seamlessly with popular frontend frameworks.

To deploy our app, we usually need to connect our hosting platform to our version control system, configure any necessary environment variables, and trigger the deployment process. The specific steps may vary depending on the hosting platform, so it's best to consult their documentation for detailed instructions.

Conclusion

In this tutorial, we have learned how to build real-time apps with Supabase. We started by setting up Supabase, creating the user interface, and handling real-time updates using the Supabase Realtime feature. We also implemented user authentication using the Supabase Auth feature. Furthermore, we explored how to integrate Supabase with other technologies such as React and GraphQL. Finally, we discussed the process of deploying the app to a hosting platform.

Supabase provides developers with a powerful and convenient way to build real-time apps without the need for extensive backend development. With its seamless integration with PostgreSQL and its rich set of features, Supabase offers a compelling alternative to existing backend-as-a-service platforms. By following the steps outlined in this tutorial, you can start building your own real-time apps with Supabase and unleash the full potential of real-time functionality in your applications.