This is a simple example of how to upload an avatar image to a user's profile using InstantDB
Clone the repo and install the dependencies
git clone ...
cd instant-storage-avatar-example
npm installInitialize your schema and permissions via the Instant CLI
npx instant-cli@latest init
Now open instant.shema.ts and replace the contents with the following code.
import { i } from "@instantdb/react";
const _schema = i.schema({
entities: {
$files: i.entity({
path: i.string().unique().indexed(),
url: i.string(),
}),
$users: i.entity({
email: i.string().unique().indexed(),
}),
profiles: i.entity({
createdAt: i.date().indexed(),
nickname: i.string().unique().indexed(),
}),
},
links: {
profiles$user: {
forward: {
on: 'profiles',
has: 'one',
label: '$user',
},
reverse: {
on: '$users',
has: 'one',
label: 'profile',
},
},
profilesAvatar: {
forward: {
on: 'profiles',
has: 'one',
label: 'avatar',
},
// Notice that $files is on the reverse side
reverse: {
on: '$files',
has: 'one',
label: 'profile',
},
},
},
rooms: {},
});
// This helps Typescript display nicer intellisense
type _AppSchema = typeof _schema;
interface AppSchema extends _AppSchema {}
const schema: AppSchema = _schema;
export type { AppSchema };
export default schema;Similarly open instant.perms.ts and replace the contents with the following
// Docs: https://www.instantdb.com/docs/permissions
import type { InstantRules } from "@instantdb/react";
const rules = {
"$files": {
"allow": {
"view": "true",
"create": "isLoggedIn && isOwner",
"delete": "isLoggedIn && isOwner"
},
"bind": [
"isLoggedIn", "auth.id != null",
"isOwner", "data.path.startsWith(auth.id + '/')"
]
}
} satisfies InstantRules;
export default rules;Push up both the schema and permissions to your Instant app with the following command
npx instant-cli@latest pushWith your schema, permissions, and application code set, you can now run your app!
npm run devGo to localhost:3000 and you should see a login screen. Log in with your email
and magic code. You'll now see a page for uploading avatars. Huzzah!
The main files to look at are
- instant.schema.ts - Defines
$users,$files,profilesand their relationships for implementing avatar uploads. - instant.perms.ts -- Locks down the
$filestable to only allow users to upload their own files. - app/page.tsx - The main page of the app. It contains the form for uploading the avatar image and the logic for displaying the uploaded image.
- app/db.tsx - Exports the
dbinstance for other parts of the app to use.
To learn more, see InstantDB's storage docs. info on get this example up and running.