Throughout this guide, we’ll utilize the @nhost/react-native-template, which comes pre-configured with authentication and storage capabilities provided by Nhost.


Before starting this quickstart, ensure that your environment is set up to work with React Native. Follow the setup guide available on the official React Native website.

1

Create Nhost Project

Create your project through the Nhost Dashboard.

2

Setup Database

Navigate to the SQL Editor of the database and run the following SQL to create a new table todos.

Make sure the option Track this is enabled
SQL Editor
CREATE TABLE todos (
  id uuid NOT NULL DEFAULT gen_random_uuid(),
  created_at timestamptz NOT NULL DEFAULT now(),
  updated_at timestamptz NOT NULL DEFAULT now(),
  user_id uuid NOT NULL,
  contents text NOT NULL,
  PRIMARY KEY (id),
  FOREIGN KEY (user_id) REFERENCES auth.users(id) ON UPDATE cascade ON DELETE cascade 
);

Create Todos Table

3

Configure the todos table permissions

To set permissions for the new todos table, select the table, click on the ... to open the actions dialog, then click on Edit Permissions. Set the following permissions for the user role:

  1. Insert
    • Set Row insert permissions to Without any checks
    • Select all columns except user_id on Column insert permissions
    • Add a new Column preset and set Column Name to user_id and Column Value to X-Hasura-User-Id
    • Save

Insert Permissions

  1. Select
    • Set Row select permissions to With custom check and fill in the following rule:
      • Set Where to todos.user_id
      • Set the operator to _eq
      • Set the value to X-Hasura-User-Id
    • Select all columns except user_id on Column select permissions
    • Save

Select Permissions

  1. Update
    • Set Row update permissions to With custom check and fill in the following rule:
      • Set Where to todos.user_id
      • Set the operator to _eq
      • Set the value to X-Hasura-User-Id
    • Select all columns except user_id on Column select permissions
    • Save

Update permissions

  1. Delete
    • Set Row delete permissions to With custom check and fill in the following rule:
      • Set Where to todos.user_id
      • Set the operator to _eq
      • Set the value to X-Hasura-User-Id
    • Save

Delete permissions

4

Configure permissions to enable user file uploads

To enable file uploads by users, set the permissions as follows:

  1. Edit the files table permissions

    1. Navigate to the files table within the Database tab
    2. Click on the three dots (…) next to the files table
    3. Click on Edit Permissions
  2. Modify the Insert permission for the user role:

    1. Set Row insert permissions to Without any checks
    2. Select all columns on Column insert permissions
    3. Save

Insert Permissions

  1. Select
    • Set Row select permissions to With custom check and fill in the following rule:
      • Set Where to files.uploaded_by_user_id
      • Set the operator to _eq
      • Set the value to X-Hasura-User-Id
    • Select all columns on Column select permissions
    • Save

Select permissions

5

Bootstrap your React Native app

Intialize a new React Native project using the template @nhost/react-native-template

Terminal
npx react-native init myapp --template @nhost/react-native-template
6

Connect your React Native app to the Nhost project

Copy your project’s <subdomain> and <region> values available on the dashboard overview

src/root.tsx
const nhost = new NhostClient({
  subdomain: "<subdomain>", // replace the subdomain value e.g. "hjcuuqweqwezolpolrep"
  region: "<region>", // replace the region value e.g. "eu-central-1"
  clientStorageType: 'react-native',
  clientStorage: AsyncStorage,
});
7

Add the GraphQL queries

Create a new file src/graphql/todos.ts that will expose the graphql queries needed to list, add and delete To-Do’s.

src/graphql/todos.ts
import {gql} from '@apollo/client';

export const GET_TODOS = gql`
  query listTodos {
    todos(order_by: { created_at: desc }) {
      id
      contents
    }
  }
`;

export const ADD_TODO = gql`
  mutation addTodo($contents: String!) {
    insert_todos_one(object: { contents: $contents }) {
      id
      contents
    }
  }
`;

export const DELETE_TODO = gql`
  mutation deleteTodo($id: uuid!) {
    delete_todos_by_pk(id: $id) {
      __typename
    }
  }
`;
8

Add a form to insert a To-Do

src/components/AddTodoForm.tsx
import React from 'react';
import {useMutation} from '@apollo/client';
import Button from '@components/Button';
import ControlledInput from '@components/ControlledInput';
import {ADD_TODO, GET_TODOS} from '@graphql/todos';
import {useForm} from 'react-hook-form';
import {StyleSheet, View} from 'react-native';

interface AddTodoFormValues {
  contents: string;
}

export default function AddTodoForm() {
  const {control, handleSubmit, reset} = useForm<AddTodoFormValues>();

  const [addTodo, {loading}] = useMutation(ADD_TODO, {
    refetchQueries: [{query: GET_TODOS}],
  });

  const onSubmit = async (values: AddTodoFormValues) => {
    const {contents} = values;
    await addTodo({variables: {contents}});
    reset();
  };

  return (
    <View style={styles.wrapper}>
      <View style={styles.inputWrapper}>
        <ControlledInput
          control={control}
          name="contents"
          placeholder="New To-Do"
          autoCapitalize="none"
          rules={{
            required: true,
          }}
        />
      </View>
      <View style={styles.buttonWrapper}>
        <Button
          label="Add"
          onPress={handleSubmit(onSubmit)}
          disabled={loading}
          loading={loading}
        />
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  wrapper: {
    gap: 12,
    padding: 12,
    flexDirection: 'row',
    backgroundColor: 'white',
  },
  inputWrapper: {
    flex: 3,
  },
  buttonWrapper: {
    flex: 1,
  },
});
9

Add the Todo component and the screen to list all the todos

10

Reference the new Todos components in the Drawer Navigator

src/screens/Main.tsx
function DrawerNavigator() {
  return (
    <Drawer.Navigator
      screenOptions={screenOptions}
      drawerContent={drawerContent}>
      <Drawer.Screen name="Profile" component={Profile} />
      {/* Add the Todos component here */}
      <Drawer.Screen name="Todos" component={Todos} />
      <Drawer.Screen name="Storage" component={Storage} />
    </Drawer.Navigator>
  );
}
11

Run the app on the emulator

  1. Open a terminal and start the metro bundler
Terminal
cd myapp
npm start
  1. Open a new terminal and run the app on Android
Terminal
cd myapp
npm run android
12

Demo

Next Steps: enabling Google and Apple Sign-In

The template is preconfigured to allow users to sign in with Google and Apple. To enable this feature, follow these steps:

  1. Navigate to your Nhost project’s Sign-In Methods settings.
  2. Enable Google and/or Apple sign-in.
  3. Fill in the necessary credentials.

For detailed instructions on generating the required credentials, refer to the following guides: