---
title: Get up and running with Nhost and React Native
sidebarTitle: React Native
description: In this quickstart guide, we'll demonstrate how to build a simple To-Do feature using Nhost and React Native.
icon: mobile-notch
---
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](https://reactnative.dev/docs/next/set-up-your-environment) available on
the official React Native website.
Create your project through the [Nhost Dashboard](https://app.nhost.io).
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 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
);
```

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

2. `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

3. `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

4. `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

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](https://app.nhost.io/_/_/database/browser/default/storage/files)
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`
4. Save

3. `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

Intialize a new React Native project using the template `@nhost/react-native-template`
```bash Terminal
npx react-native init myapp --template @nhost/react-native-template
```
Copy your project's `` and `` values available on the dashboard overview
```tsx src/root.tsx
const nhost = new NhostClient({
subdomain: "", // replace the subdomain value e.g. "hjcuuqweqwezolpolrep"
region: "", // replace the region value e.g. "eu-central-1"
clientStorageType: 'react-native',
clientStorage: AsyncStorage,
});
```
Create a new file `src/graphql/todos.ts` that will expose the graphql queries needed to `list`, `add` and `delete` To-Do's.
```ts 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
}
}
`;
```
```tsx 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();
const [addTodo, {loading}] = useMutation(ADD_TODO, {
refetchQueries: [{query: GET_TODOS}],
});
const onSubmit = async (values: AddTodoFormValues) => {
const {contents} = values;
await addTodo({variables: {contents}});
reset();
};
return (
);
}
const styles = StyleSheet.create({
wrapper: {
gap: 12,
padding: 12,
flexDirection: 'row',
backgroundColor: 'white',
},
inputWrapper: {
flex: 3,
},
buttonWrapper: {
flex: 1,
},
});
```
```tsx src/components/Todo.tsx
import React from 'react';
import {useMutation} from '@apollo/client';
import {DELETE_TODO, GET_TODOS} from '@graphql/todos';
import {StyleSheet, Text, View} from 'react-native';
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
import Button from './Button';
export interface TodoItem {
id: string;
contents: string;
}
export default function Todo({todo: {id, contents}}: {todo: TodoItem}) {
const [deleteTodo] = useMutation(DELETE_TODO, {
variables: {id},
refetchQueries: [{query: GET_TODOS}],
});
const handleDeleteTodo = async () => {
await deleteTodo();
};
return (
{contents}
}
color="#f1f1f1"
onPress={handleDeleteTodo}
/>
);
}
const styles = StyleSheet.create({
wrapper: {
padding: 14,
flexDirection: 'row',
alignItems: 'center',
},
todoContentWrapper: {
flex: 1,
flexDirection: 'row',
alignItems: 'center',
gap: 20,
},
todoContent: {flex: 1},
buttonWrapper: {
width: 50,
},
});
```
```tsx src/screens/Todos.tsx
import React from 'react';
import {useQuery} from '@apollo/client';
import AddTodoForm from '@components/AddTodoForm';
import Todo, {type TodoItem} from '@components/Todo';
import {GET_TODOS} from '@graphql/todos';
import {useEffect} from 'react';
import {ActivityIndicator, FlatList, StyleSheet, View} from 'react-native';
export default function Todos() {
const {loading, data, client} = useQuery<{todos: TodoItem[]}>(GET_TODOS);
const todos = data?.todos || [];
useEffect(() => {
return () => client.stop();
}, [client]);
if (loading) {
return (
);
}
const renderTodo = ({item}: {item: TodoItem}) => ;
const itemSeperator = () => ;
return (
item.id}
renderItem={renderTodo}
ItemSeparatorComponent={itemSeperator}
/>
);
}
const styles = StyleSheet.create({
loadingViewWrapper: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
wrapper: {
flex: 1,
backgroundColor: 'white',
},
separator: {
height: 1,
backgroundColor: '#f1f1f1',
},
});
```
```tsx src/screens/Main.tsx
function DrawerNavigator() {
return (
{/* Add the Todos component here */}
);
}
```
1. Open a terminal and start the metro bundler
```bash Terminal
cd myapp
npm start
```
2. Open a new terminal and run the app on Android
```bash Terminal
cd myapp
npm run android
```
1. Make sure the iOS project cocopods are installed
```bash Terminal
cd ios
pod install
```
1. Install the `ios-deploy` CLI
```bash Terminal
npm install -g ios-deploy
```
2. Start the metro bundler
```bash Terminal
cd myapp
npm start
```
3. Open a new terminal and run the app on Android
```bash Terminal
cd myapp
npm run ios --interactive
```
### 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](https://app.nhost.io/_/_/settings/sign-in-methods).
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:
- [Google Sign-In Guide](https://docs.nhost.io/products/auth/social/sign-in-google)
- [Apple Sign-In Guide](https://docs.nhost.io/products/auth/social/sign-in-apple)