mirror of
https://github.com/supabase/supabase.git
synced 2026-10-15 14:19:11 +03:00
docs: changed with-expo documentation
This commit is contained in:
1 parent
7b5a5cae9b
commit
562db96e4d
1 file changed
+39
-53
@@ -1,13 +1,13 @@
|
||||
---
|
||||
id: with-expo
|
||||
title: "Quickstart: Expo"
|
||||
title: 'Quickstart: Expo'
|
||||
description: Learn how to use Supabase in your React Native App.
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import Tabs from '@theme/Tabs'
|
||||
import TabItem from '@theme/TabItem'
|
||||
|
||||
## Intro
|
||||
## Intro
|
||||
|
||||
This example provides the steps to build a simple user management app (from scratch!) using Supabase and React Native. It includes:
|
||||
|
||||
@@ -21,20 +21,19 @@ By the end of this guide you'll have an app which allows users to login and upda
|
||||
|
||||
## Project set up
|
||||
|
||||
Before we start building we're going to set up our Database and API. This is as simple as starting a new Project in Supabase
|
||||
Before we start building we're going to set up our Database and API. This is as simple as starting a new Project in Supabase
|
||||
and then creating a "schema" inside the database.
|
||||
|
||||
### Create a project
|
||||
### Create a project
|
||||
|
||||
1. Go to [app.supabase.io](https://app.supabase.io).
|
||||
1. Click on "New Project".
|
||||
1. Enter your project details.
|
||||
1. Wait for the new database to launch.
|
||||
|
||||
|
||||
### Set up the database schema
|
||||
|
||||
Now we are going to set up the database schema. We can use the "User Management Starter" quickstart in the SQL Editor,
|
||||
Now we are going to set up the database schema. We can use the "User Management Starter" quickstart in the SQL Editor,
|
||||
or you can just copy/paste the SQL from below and run it yourself.
|
||||
|
||||
<Tabs
|
||||
@@ -52,7 +51,7 @@ values={[
|
||||
```
|
||||
|
||||
<video width="99%" muted playsInline controls="true">
|
||||
<source src="/docs/videos/sql-user-management-starter.mp4" type="video/mp4" muted playsInline />
|
||||
<source src="/docs/videos/sql-user-management-starter.mp4" type="video/mp4" muted playsInline />
|
||||
</video>
|
||||
|
||||
</TabItem>
|
||||
@@ -110,11 +109,9 @@ create policy "Anyone can upload an avatar."
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### Get the API Keys
|
||||
|
||||
### Get the API Keys
|
||||
|
||||
|
||||
Now that you've created some database tables, you are ready to insert data using the auto-generated API.
|
||||
Now that you've created some database tables, you are ready to insert data using the auto-generated API.
|
||||
We just need to get the URL and `anon` key from the API settings.
|
||||
|
||||
<Tabs
|
||||
@@ -132,7 +129,7 @@ values={[
|
||||
```
|
||||
|
||||
<video width="99%" muted playsInline controls="true">
|
||||
<source src="/docs/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
|
||||
<source src="/docs/videos/api/api-url-and-key.mp4" type="video/mp4" muted playsInline />
|
||||
</video>
|
||||
|
||||
</TabItem>
|
||||
@@ -144,7 +141,7 @@ Let's start building the React Native app from scratch.
|
||||
|
||||
### Initialize a React Native app
|
||||
|
||||
We can use [`expo`](https://docs.expo.dev/get-started/create-a-new-app/) to initialize
|
||||
We can use [`expo`](https://docs.expo.dev/get-started/create-a-new-app/) to initialize
|
||||
an app called `supabaseReactNative`:
|
||||
|
||||
```bash
|
||||
@@ -160,32 +157,36 @@ Then let's install the additional dependencies: [supabase-js](https://github.com
|
||||
yarn add @supabase/supabase-js
|
||||
yarn add react-native-elements
|
||||
yarn add react-native-safe-area-context
|
||||
yarn add @react-native-async-storage/async-storage
|
||||
```
|
||||
|
||||
Now let's create a helper file to initialize the Supabase client.
|
||||
We need the API URL and the `anon` key that you copied [earlier](#get-the-api-keys).
|
||||
These variables will be exposed on the browser, and that's completely fine since we have
|
||||
These variables will be exposed on the browser, and that's completely fine since we have
|
||||
[Row Level Security](/docs/guides/auth#row-level-security) enabled on our Database.
|
||||
|
||||
```js title="lib/supabase.js"
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage'
|
||||
import { createClient } from '@supabase/supabase-js'
|
||||
|
||||
const supabaseUrl = YOUR_REACT_NATIVE_SUPABASE_URL
|
||||
const supabaseAnonKey = YOUR_REACT_NATIVE_SUPABASE_ANON_KEY
|
||||
|
||||
export const supabase = createClient(supabaseUrl, supabaseAnonKey)
|
||||
export const supabase = createClient(supabaseUrl, supabaseAnonKey, {
|
||||
localStorage: AsyncStorage,
|
||||
})
|
||||
```
|
||||
|
||||
### Set up a Login component
|
||||
|
||||
Let's set up a React Native component to manage logins and sign ups.
|
||||
Let's set up a React Native component to manage logins and sign ups.
|
||||
Users would be able to sign in with their email and password.
|
||||
|
||||
```jsx title="components/Auth.js"
|
||||
import React, {useState} from 'react'
|
||||
import {Alert, StyleSheet, View} from 'react-native'
|
||||
import {supabase} from '../lib/supabase'
|
||||
import {Button, Input} from 'react-native-elements'
|
||||
import React, { useState } from 'react'
|
||||
import { Alert, StyleSheet, View } from 'react-native'
|
||||
import { supabase } from '../lib/supabase'
|
||||
import { Button, Input } from 'react-native-elements'
|
||||
|
||||
export default function Auth() {
|
||||
const [email, setEmail] = useState('')
|
||||
@@ -211,8 +212,8 @@ export default function Auth() {
|
||||
<View style={[styles.verticallySpaced, styles.mt20]}>
|
||||
<Input
|
||||
label="Email"
|
||||
leftIcon={{type: 'font-awesome', name: 'envelope'}}
|
||||
onChangeText={text => setEmail(text)}
|
||||
leftIcon={{ type: 'font-awesome', name: 'envelope' }}
|
||||
onChangeText={(text) => setEmail(text)}
|
||||
value={email}
|
||||
placeholder="email@address.com"
|
||||
autoCapitalize={'none'}
|
||||
@@ -221,8 +222,8 @@ export default function Auth() {
|
||||
<View style={styles.verticallySpaced}>
|
||||
<Input
|
||||
label="Password"
|
||||
leftIcon={{type: 'font-awesome', name: 'lock'}}
|
||||
onChangeText={text => setPassword(text)}
|
||||
leftIcon={{ type: 'font-awesome', name: 'lock' }}
|
||||
onChangeText={(text) => setPassword(text)}
|
||||
value={password}
|
||||
secureTextEntry={true}
|
||||
placeholder="Password"
|
||||
@@ -230,19 +231,13 @@ export default function Auth() {
|
||||
/>
|
||||
</View>
|
||||
<View style={[styles.verticallySpaced, styles.mt20]}>
|
||||
<Button
|
||||
title="Sign in"
|
||||
onPress={() => signInWithEmail()}
|
||||
/>
|
||||
<Button title="Sign in" onPress={() => signInWithEmail()} />
|
||||
</View>
|
||||
<View style={styles.verticallySpaced}>
|
||||
<Button
|
||||
title="Sign up"
|
||||
onPress={() => signUpWithEmail()}
|
||||
/>
|
||||
<Button title="Sign up" onPress={() => signUpWithEmail()} />
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
@@ -258,7 +253,7 @@ const styles = StyleSheet.create({
|
||||
mt20: {
|
||||
marginTop: 20,
|
||||
},
|
||||
});
|
||||
})
|
||||
```
|
||||
|
||||
### Account page
|
||||
@@ -270,9 +265,9 @@ Let's create a new component for that called `Account.js`.
|
||||
```jsx title="components/Account.js"
|
||||
import { useState, useEffect } from 'react'
|
||||
import { supabase } from '../lib/supabase'
|
||||
import {StyleSheet, View} from 'react-native'
|
||||
import { StyleSheet, View } from 'react-native'
|
||||
|
||||
import {Button, Input} from 'react-native-elements'
|
||||
import { Button, Input } from 'react-native-elements'
|
||||
|
||||
export default function Account({ session }) {
|
||||
const [loading, setLoading] = useState(true)
|
||||
@@ -379,7 +374,6 @@ export default function Account({ session }) {
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### Launch!
|
||||
@@ -420,22 +414,21 @@ yarn start
|
||||
|
||||
And then open the browser to [localhost:3000](http://localhost:3000) and you should see the completed app.
|
||||
|
||||
|
||||
## Bonus: Profile photos
|
||||
|
||||
Every Supabase project is configured with [Storage](/docs/guides/storage) for managing large files like
|
||||
Every Supabase project is configured with [Storage](/docs/guides/storage) for managing large files like
|
||||
photos and videos.
|
||||
|
||||
### Create an upload widget
|
||||
|
||||
Let's create an avatar for the user so that they can upload a profile photo.
|
||||
Let's create an avatar for the user so that they can upload a profile photo.
|
||||
We can start by creating a new component:
|
||||
|
||||
```jsx title="components/Avatar.js"
|
||||
import { useEffect, useState } from 'react'
|
||||
import { supabase } from '../lib/supabase'
|
||||
import {Alert, StyleSheet, View, Image} from 'react-native'
|
||||
import {Button, Input} from 'react-native-elements'
|
||||
import { Alert, StyleSheet, View, Image } from 'react-native'
|
||||
import { Button, Input } from 'react-native-elements'
|
||||
|
||||
export default function Avatar({ url, size, onUpload }) {
|
||||
const [avatarUrl, setAvatarUrl] = useState(null)
|
||||
@@ -458,7 +451,6 @@ export default function Avatar({ url, size, onUpload }) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async function uploadAvatar(event) {
|
||||
try {
|
||||
setUploading(true)
|
||||
@@ -472,9 +464,7 @@ export default function Avatar({ url, size, onUpload }) {
|
||||
const fileName = `${Math.random()}.${fileExt}`
|
||||
const filePath = `${fileName}`
|
||||
|
||||
let { error: uploadError } = await supabase.storage
|
||||
.from('avatars')
|
||||
.upload(filePath, file)
|
||||
let { error: uploadError } = await supabase.storage.from('avatars').upload(filePath, file)
|
||||
|
||||
if (uploadError) {
|
||||
throw uploadError
|
||||
@@ -491,11 +481,7 @@ export default function Avatar({ url, size, onUpload }) {
|
||||
return (
|
||||
<View>
|
||||
{avatarUrl ? (
|
||||
<Image
|
||||
src={avatarUrl}
|
||||
alt="Avatar"
|
||||
className="avatar image"
|
||||
/>
|
||||
<Image src={avatarUrl} alt="Avatar" className="avatar image" />
|
||||
) : (
|
||||
<View className="avatar no-image" />
|
||||
)}
|
||||
|
||||
Reference in new issue
Block a user