> ## Documentation Index
> Fetch the complete documentation index at: https://docs.newly.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Connecting a Database

> Store and retrieve data in your app

# Connecting a Database

This guide explains how to store, retrieve, and manage data in your Newly app using the built-in Liquid Backend.

## When You Need a Database

You need a database when:

* Data should persist across app restarts
* Data should sync across devices
* Users need their own personal data
* You're building any CRUD application

## Basic Data Storage

### Creating a Simple Feature

Let's build a notes app to demonstrate database concepts:

```
Create a notes app where users can:
- View a list of their notes
- Tap a note to see full content
- Create new notes with title and content
- Edit existing notes
- Delete notes

Store notes in the database so they persist.
Each user should only see their own notes.
```

<Note>
  When you request data persistence, Liquid Backend automatically creates the necessary database tables and API endpoints.
</Note>

## Understanding the Data Model

### How the AI Creates Tables

The AI analyzes your request and creates an appropriate schema:

```sql theme={null}
-- Example generated table for notes
CREATE TABLE notes (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id TEXT NOT NULL,
  title TEXT NOT NULL,
  content TEXT,
  created_at TIMESTAMP DEFAULT NOW(),
  updated_at TIMESTAMP DEFAULT NOW()
);
```

### Being Explicit About Schema

For complex data, be specific:

```
Create a recipes feature with this data structure:

Recipes table:
- id (unique identifier)
- title (required, text)
- description (optional, text)
- prep_time (number, in minutes)
- cook_time (number, in minutes)
- servings (number)
- image_url (optional, text)
- created_at (timestamp)
- user_id (link to user)

Ingredients table (linked to recipes):
- id (unique)
- recipe_id (link to recipe)
- name (required, text)
- quantity (text, like "2 cups")
- order (number, for sorting)

Each user can only see their own recipes.
```

## CRUD Operations

### Create (Adding Data)

```
When the user submits the new recipe form:
1. Validate all required fields are filled
2. Save the recipe to the database
3. Navigate back to the recipe list
4. Show a success toast: "Recipe saved!"
```

### Read (Fetching Data)

```
On the recipes list screen:
1. Fetch all recipes for the current user
2. Order by created_at, newest first
3. Show a loading spinner while fetching
4. Show "No recipes yet" if empty
```

### Update (Editing Data)

```
Add an edit button on the recipe detail screen:
1. Tapping it shows the recipe form with existing data
2. User can modify any field
3. On save, update the recipe in the database
4. Show success toast and return to detail view
```

### Delete (Removing Data)

```
Add delete functionality:
1. Long press on a recipe shows delete option
2. Show confirmation dialog: "Delete this recipe?"
3. On confirm, delete from database
4. Remove from list with animation
```

## Relationships Between Data

### One-to-Many Relationships

```
Each recipe has many ingredients.
When viewing a recipe, show its ingredients.
When deleting a recipe, also delete its ingredients.
```

### Fetching Related Data

```
On the recipe detail screen:
- Fetch the recipe by ID
- Also fetch all ingredients for this recipe
- Display ingredients in order
```

## Querying and Filtering

### Search

```
Add a search bar to the recipes list:
- Filter recipes as the user types
- Search both title and description
- Show "No results" if nothing matches
```

### Sorting

```
Add a sort option to recipes:
- Sort by newest first (default)
- Sort by prep time (shortest first)
- Sort alphabetically by title
```

### Filtering

```
Add category filtering:
- Each recipe has a category (breakfast, lunch, dinner, dessert)
- Add filter chips at the top of the list
- Tapping a chip shows only that category
```

## Optimistic Updates

For better UX, update the UI before the server responds:

```
When marking a task complete:
1. Immediately show it as complete (optimistic update)
2. Send the update to the server in background
3. If the server request fails, revert the change
4. Show an error toast if it fails
```

## Error Handling

```
Handle database errors gracefully:
- If save fails, show error message and keep form data
- If fetch fails, show retry button
- If delete fails, show error and keep item in list
- Always show user-friendly error messages
```

## Viewing Your Data

Use the Database Viewer to inspect your data:

1. Click the **Database** icon in the preview header
2. Select a table from the sidebar
3. Browse records and their values

This is useful for:

* Debugging data issues
* Verifying saves work correctly
* Understanding the data structure

## Best Practices

<CardGroup cols={2}>
  <Card title="Validate Before Saving" icon="check">
    Check data is valid before sending to server
  </Card>

  <Card title="Show Loading States" icon="spinner">
    Indicate when data is being fetched or saved
  </Card>

  <Card title="Handle Errors" icon="triangle-exclamation">
    Always handle and display errors gracefully
  </Card>

  <Card title="Use Optimistic Updates" icon="bolt">
    Update UI immediately for better responsiveness
  </Card>
</CardGroup>

## Next Steps

<CardGroup cols={2}>
  <Card title="Add Authentication" icon="user" href="/guides/adding-authentication">
    Secure your data with user accounts
  </Card>

  <Card title="Supabase Integration" icon="database" href="/integrations/supabase">
    Use Supabase for advanced features
  </Card>
</CardGroup>
