Files
supabase/apps/reference/docs/guides/storage.mdx
Thor 雷神 Schaeff 8bf9cd1477 chore: docs cleanup oct 22 (#9697)
* chore: update links

* chore: move duplicate sections into components.

* fix: auth-helpers-nextjs docs

* chore: rename to _partials.

Co-authored-by: Copple <10214025+kiwicopple@users.noreply.github.com>
2022-10-21 15:55:39 +02:00

376 lines
11 KiB
Plaintext

---
id: storage
title: Storage
description: Use Supabase to store and serve files.
sidebar_label: Overview
---
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
Supabase Storage makes it simple to store and serve large files.
### Files
Files can be any sort of media file. This includes images, GIFs, and videos. It is best practice to store files outside of your database because of their sizes.
### Folders
Folders are a way to organize your files (just like on your computer).
There is no right or wrong way to
organize your files. You can store them in whichever folder structure suits your project.
### Buckets
Buckets are distinct containers for files and folders. You can think of them like "super folders".
Generally you would create distinct buckets for different Security and Access Rules. For example, you might
keep all video files in a "video" bucket, and profile pictures in an "avatar" bucket.
<div class="video-container">
<iframe
src="https://www.youtube-nocookie.com/embed/J9mTPY8rIXE"
frameBorder="1"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
</div>
## Getting started
This is a quick guide that shows the basic functionality of Supabase Storage. Find a full
[example application in GitHub](https://github.com/supabase/supabase/tree/master/examples/user-management/nextjs-ts-user-management),
which you can deploy yourself.
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/git/external?repository-url=https%3A%2F%2Fgithub.com%2Fsupabase%2Fsupabase%2Ftree%2Fmaster%2Fexamples%2Fuser-management%2Fnextjs-ts-user-management&project-name=supabase-user-management&repository-name=supabase-user-management&demo-title=Supabase%20User%20Management&demo-description=An%20example%20web%20app%20using%20Supabase%20and%20Next.js&demo-url=https%3A%2F%2Fsupabase-nextjs-ts-user-management.vercel.app&demo-image=https%3A%2F%2Fi.imgur.com%2FZ3HkQqe.png&integration-ids=oac_jUduyjQgOyzev1fjrW83NYOv&external-id=nextjs-user-management)
:::note
File, Folder, and Bucket names **must follow** [AWS object key naming guidelines](https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html) and avoid use of any other characters.
:::
### Create a bucket
You can create a bucket using the Supabase Dashboard.
Since the storage is interoperable with your Postgres database, you can also use SQL or our
client libraries. Here we create a bucket called "avatars":
<Tabs
groupId="storage-tabs"
defaultValue="dashboard"
values={[
{label: 'Dashboard', value: 'dashboard'},
{label: 'SQL', value: 'sql'},
{label: 'JavaScript', value: 'javascript'},
{label: 'Dart', value: 'dart'},
]}>
<TabItem value="dashboard">
1. Go to the [Storage](https://app.supabase.com/project/_/storage/buckets) page in the Dashboard.
2. Click **New Bucket** and enter a name for the bucket.
3. Click **Create Bucket**.
</TabItem>
<TabItem value="sql">
```sql
-- Use Postgres to create a bucket.
insert into storage.buckets (id, name)
values ('avatars', 'avatars');
```
</TabItem>
<TabItem value="javascript">
```js
// Use the JS library to create a bucket.
const { data, error } = await supabase.storage.createBucket('avatars')
```
[Reference.](/docs/reference/javascript/storage-createbucket)
</TabItem>
<TabItem value="dart">
```dart
void main() async {
final client = SupabaseClient('supabaseUrl', 'supabaseKey');
final storageResponse = await client
.storage
.createBucket('avatars');
}
```
[Reference.](https://pub.dev/documentation/storage_client/latest/storage_client/SupabaseStorageClient/createBucket.html)
</TabItem>
</Tabs>
### Upload a file
You can upload a file from the Dashboard, or within a browser using our JS libraries.
<Tabs
groupId="storage-tabs"
defaultValue="dashboard"
values={[
{label: 'Dashboard', value: 'dashboard'},
{label: 'JavaScript', value: 'javascript'},
{label: 'Dart', value: 'dart'},
]}>
<TabItem value="dashboard">
1. Go to the [Storage](https://app.supabase.com/project/_/storage/buckets) page in the Dashboard.
2. Select the bucket you want to upload the file to.
3. Click **Upload File**.
4. Select the file you want to upload.
</TabItem>
<TabItem value="javascript">
```js
const avatarFile = event.target.files[0]
const { data, error } = await supabase.storage
.from('avatars')
.upload('public/avatar1.png', avatarFile)
```
[Reference.](/docs/reference/javascript/storage-from-upload)
</TabItem>
<TabItem value="dart">
```dart
void main() async {
final client = SupabaseClient('supabaseUrl', 'supabaseKey');
// Create file `example.txt` and upload it in `public` bucket
final file = File('example.txt');
file.writeAsStringSync('File content');
final storageResponse = await client
.storage
.from('public')
.upload('example.txt', file);
}
```
</TabItem>
</Tabs>
### Download a file
You can download a file from the Dashboard, or within a browser using our JS libraries.
<Tabs
groupId="storage-tabs"
defaultValue="dashboard"
values={[
{label: 'Dashboard', value: 'dashboard'},
{label: 'JavaScript', value: 'javascript'},
{label: 'Dart', value: 'dart'},
]}>
<TabItem value="dashboard">
1. Go to the [Storage](https://app.supabase.com/project/_/storage/buckets) page in the Dashboard.
2. Select the bucket that contains the file.
3. Select the file that you want to download.
4. Click **Download**.
</TabItem>
<TabItem value="javascript">
```js
// Use the JS library to download a file.
const { data, error } = await supabase.storage
.from('avatars')
.download('public/avatar1.png')
```
[Reference.](/docs/reference/javascript/storage-from-download)
</TabItem>
<TabItem value="dart">
```dart
void main() async {
final client = SupabaseClient('supabaseUrl', 'supabaseKey');
final storageResponse = await client
.storage
.from('public')
.download('example.txt');
}
```
</TabItem>
</Tabs>
### Add security rules
To restrict access to your files you can use either the Dashboard or SQL.
<Tabs
groupId="storage-tabs"
defaultValue="dashboard"
values={[
{label: 'Dashboard', value: 'dashboard'},
{label: 'SQL', value: 'sql'}
]}>
<TabItem value="dashboard">
1. Go to the [Storage](https://app.supabase.com/project/_/storage/buckets) page in the Dashboard.
2. Click **Policies** in the sidebar.
3. Click **Add Policies** in the `OBJECTS` table to add policies for Files. You can also create policies for Buckets.
4. Choose whether you want the policy to apply to downloads (SELECT), uploads (INSERT), updates (UPDATE), or deletes (DELETE).
5. Give your policy a unique name.
6. Write the policy using SQL.
</TabItem>
<TabItem value="sql">
```sql
-- Use SQL to create a policy.
create policy "Public Access"
on storage.objects for select
using ( bucket_id = 'public' );
```
</TabItem>
</Tabs>
## Public and Private Buckets
Storage buckets are private by default.
For private buckets, you can access objects via the [download](/docs/reference/javascript/storage-from-download) method. This corresponds to `/object/auth/` API endpoint.
Alternatively, you can create a publicly shareable URL with an expiry date using the [createSignedUrl](/docs/reference/javascript/storage-from-createsignedurl) method
which calls the `/object/sign/` API.
For public buckets, you can access the assets directly without a token or an Authorisation header. The [getPublicUrl](/docs/reference/javascript/storage-from-getpublicurl)
helper method returns the full public URL for an asset. This calls the `/object/public/` API endpoint internally. While no authorization is required for accessing objects in a public bucket, proper [access control](#access-control) is required for other operations like uploading, deleting objects from public buckets as well.
Public buckets also tend to have [better performance](/docs/guides/storage-cdn#public-vs-private-buckets).
<details>
<summary>Advanced: reverse proxy</summary>
The URLs returned are proxied through the API Proxy. They are prefixed by <code>/storage/v1</code>.
For example, on the hosted Platform they will be
<code>https://[project_ref].supabase.co/storage/v1/object/public/[id]</code>
You can access the storage API directly with the same endpoint. See the <a href="https://supabase.github.io/storage-api">API docs</a> for a full list of operations available.
</details>
---
## Access control
Supabase Storage is integrated with your [Postgres Database](/docs/guides/database).
This means that you can use the same [Row Level Security Policies](/docs/guides/auth#policies)
for managing access to your files. Supabase Storage stores metadata in the `objects` and `buckets` table in the storage schema. To allow read access to files, the RLS policy must allow users to `SELECT` the `objects` table and for uploading a new object, the RLS policy must grant users access to `INSERT` into the `objects` table and so on. The mapping between the different API calls and the database permissions required is documented in the [Reference docs](/docs/reference/javascript/storage-createbucket).
:::note
Access control for Storage is mapped to CRUD operations on the `buckets` and `objects` table via RLS policies.
:::
## Helpers
Supabase Storage provides SQL helper functions which you can use in your database queries and
policies.
---
#### `storage.filename()`
Returns the name of a file.
```sql
select storage.filename(name)
from storage.objects;
```
For example, if your file is stored in `public/subfolder/avatar.png` it would return:
`'avatar.png'`
---
#### `storage.foldername()`
Returns an array path, with all of the subfolders that a file belongs to.
```sql
select storage.foldername(name)
from storage.objects;
```
For example, if your file is stored in `public/subfolder/avatar.png` it would return:
`[ 'public', 'subfolder' ]`
---
#### `storage.extension()`
Returns the extension of a file.
```sql
select storage.extension(name)
from storage.objects;
```
For example, if your file is stored in `public/subfolder/avatar.png` it would return:
`'png'`
---
## Policy examples
Here are some examples of storage policies.
### Allow public access to a bucket
```sql
-- 1. Allow public access to any files in the "public" bucket
create policy "Public Access"
on storage.objects for select
using ( bucket_id = 'public' );
```
### Allow logged-in access to a bucket
```sql
-- 1. Allow logged-in access to any files in the "restricted" bucket
create policy "Restricted Access"
on storage.objects for select
using (
bucket_id = 'restricted'
and auth.role() = 'authenticated'
);
```
### Allow individual access to a file
```sql
-- 1. Allow a user to access their own files
create policy "Individual user Access"
on storage.objects for select
using ( auth.uid() = owner );
```
## See also
- Read more about Supabase Storage in the [blog post](https://supabase.com/blog/supabase-storage)
- [Supabase Storage on GitHub](https://github.com/supabase/storage-api)
- [Swagger API documentation](https://supabase.github.io/storage-api)
- Official [JavaScript](/docs/reference/javascript/storage-createbucket) and [Dart](/docs/reference/dart/storage-createbucket) documentation
- [Community libraries](https://github.com/supabase-community)