In this tutorial, we'll guide you through the process of using Supabase, an open-source Backend-as-a-Service (BaaS), with React Native to build a simple Todo app. We'll cover the three essential aspects of Supabase: Authentication, Database, and Functions. By the end of this tutorial, you'll have a solid understanding of how to integrate Supabase into your React Native application.
Prerequisites
Before we start, ensure that you have the following prerequisites:
- Node.js and npm installed on your machine.
- React Native development environment set up.
- Basic knowledge of React Native and JavaScript.
Setting Up the Project
Let's begin by creating a new React Native project using the following command:
npx react-native init SupabaseTodoApp
Navigate to the project directory:
cd SupabaseTodoApp
Setting Up Supabase
1. Creating a Supabase Project
- Visit the Supabase website and sign up for an account if you haven't already.
- Once logged in, create a new project.
2. Authenticating Users
Setting Up Supabase Auth
Supabase provides easy-to-use authentication APIs to manage user accounts in your app.
- Install the Supabase JavaScript client library:
npm install @supabase/supabase-js
- Initialize Supabase in your React Native app:
import { createClient } from '@supabase/supabase-js';
const supabaseUrl = 'YOUR_SUPABASE_URL';
const supabaseKey = 'YOUR_SUPABASE_API_KEY';
const supabase = createClient(supabaseUrl, supabaseKey);
Replace 'YOUR_SUPABASE_URL'
and 'YOUR_SUPABASE_API_KEY'
with your Supabase project's URL and API key.
Adding Authentication to Your App
Let's add authentication to your React Native app:
import React, { useState, useEffect } from 'react';
import { View, Text, Button } from 'react-native';
const App = () => {
const [user, setUser] = useState(null);
useEffect(() => {
const authListener = supabase.auth.onAuthStateChange((event, session) => {
setUser(session?.user ?? null);
});
return () => {
authListener.unsubscribe();
};
}, []);
const handleSignIn = async () => {
const { user, error } = await supabase.auth.signIn({
provider: 'github', // Replace with your preferred auth provider
});
};
const handleSignOut = async () => {
await supabase.auth.signOut();
};
return (
<View>
{user ? (
<View>
<Text>Welcome, {user.email}</Text>
<Button title="Sign Out" onPress={handleSignOut} />
</View>
) : (
<Button title="Sign In" onPress={handleSignIn} />
)}
</View>
);
};
export default App;
This code sets up user authentication with Supabase using the GitHub provider. Make sure to replace 'github'
with your desired authentication provider.
3. Setting Up the Database
Creating a Database Table
Supabase offers a PostgreSQL database that you can easily integrate into your React Native app.
- Open your Supabase project dashboard and go to the SQL editor.
- Create a new table called
todos
with columnsid
,task
, andcompleted
.
CREATE TABLE todos (
id SERIAL PRIMARY KEY,
task TEXT NOT NULL,
completed BOOLEAN DEFAULT false
);
4. Connecting to the Database
To interact with the database, you'll need to use the Supabase client library again.
-
Install the
@supabase/supabase-js
library if you haven't already. -
Initialize Supabase as shown earlier.
Fetching Todos
import React, { useState, useEffect } from 'react';
import { View, Text, FlatList, Button } from 'react-native';
const App = () => {
const [todos, setTodos] = useState([]);
useEffect(() => {
const fetchTodos = async () => {
const { data, error } = await supabase
.from('todos')
.select('*')
.order('id', { ascending: true });
if (error) {
console.error('Error fetching todos:', error.message);
return;
}
setTodos(data);
};
fetchTodos();
}, []);
// ...
};
This code fetches todos from the todos
table in your Supabase database and displays them in a React Native FlatList
.
Adding Todos
const App = () => {
// ...
const addTodo = async (task) => {
const { data, error } = await supabase.from('todos').upsert([
{
task,
completed: false,
},
]);
if (error) {
console.error('Error adding todo:', error.message);
return;
}
setTodos([...todos, data[0]]);
};
return (
<View>
{/* ... */}
<Button title="Add Todo" onPress={() => addTodo('New Todo')} />
</View>
);
};
This code allows you to add new todos to the todos
table.
5. Using Supabase Functions
Supabase Functions are serverless functions that you can use to run server-side logic.
Creating a Function
-
Go to your Supabase project dashboard and select "Functions."
-
Create a new function called
markTodoComplete
with the following code:
const { supabase } = require('@supabase/supabase-js');
exports.handler = async (event) => {
const { id, completed } = event.queryStringParameters;
const { data, error } = await supabase
.from('todos')
.update({ completed: completed === 'true' })
.eq('id', id);
if (error) {
return {
statusCode: 500,
body: JSON.stringify({ error: 'Error updating todo' }),
};
}
return {
statusCode: 200,
body: JSON.stringify(data),
};
};
Using the Function
import React from 'react';
import { View, Text, Button } from 'react-native';
const App = () => {
// ...
const markTodoComplete = async (id, completed) => {
const { data, error } = await fetch(
`https://YOUR_SUPABASE_URL/functions/markTodoComplete?id=${id}&completed=${completed}`,
{
method: 'POST',
}
).then((response) => response.json());
if (error) {
console.error('Error marking todo complete:', error.message);
return;
}
const updatedTodos = todos.map((todo) =>
todo.id === id ? { ...
todo, completed: completed } : todo
);
setTodos(updatedTodos);
};
return (
<View>
{/* ... */}
<Button
title="Mark as Complete"
onPress={() => markTodoComplete(todo.id, !todo.completed)}
/>
</View>
);
};
This code calls the markTodoComplete function to update the completion status of a todo.
Conclusion
Congratulations! You’ve successfully integrated Supabase into your React Native app to create a Todo app with authentication, a database, and serverless functions. This tutorial covered the basics, and you can further enhance your app’s features and security as needed. Supabase provides a powerful backend solution to help you build robust mobile applications effortlessly.