YassineBouchama
react-native

WatermelonDB: Complete Setup Guide for React Native Expo

WatermelonDB: Complete Setup Guide for React Native Expo
0 views
4 min read
#react-native

WatermelonDB is a high-performance reactive database for React Native that helps you build powerful offline-first applications. This guide will walk you through the complete setup process in a React Native Expo project.

Getting Started with WatermelonDB

Installation Steps

First, let's install all the necessary dependencies. Open your terminal and run:

# Install core and required dependenciesnpx expo install @nozbe/watermelondbnpx expo install @nozbe/watermelondb/adapters/sqlitenpx expo install react-native-quick-sqlite# Install dev dependencies for buildingnpm install --save-dev @babel/plugin-proposal-decorators

Babel Configuration

Create or modify your babel.config.js file to include the necessary plugins:

module.exports = function (api) {  api.cache(true);  return {    presets: ['babel-preset-expo'],    plugins: [      ['@babel/plugin-proposal-decorators', { legacy: true }],    ],  };};

Database Setup

1. Create Database Configuration

Create a new file database/index.js:

import { Database } from '@nozbe/watermelondb'import SQLiteAdapter from '@nozbe/watermelondb/adapters/sqlite'import { schemas } from './schema'import { models } from './models'const adapter = new SQLiteAdapter({  schema: schemas,})export const database = new Database({  adapter,  modelClasses: models,})

2. Define Your Schema

Create database/schema.js:

import { appSchema, tableSchema } from '@nozbe/watermelondb'export const schemas = appSchema({  version: 1,  tables: [    tableSchema({      name: 'posts',      columns: [        { name: 'title', type: 'string' },        { name: 'body', type: 'string' },        { name: 'created_at', type: 'number' },      ]    })  ]})

3. Create Models

Create database/models/Post.js:

import { Model } from '@nozbe/watermelondb'import { field, date } from '@nozbe/watermelondb/decorators'export class Post extends Model {  static table = 'posts'  @field('title') title  @field('body') body  @date('created_at') createdAt}

4. Set up Provider

In your App.js:

import { DatabaseProvider } from '@nozbe/watermelondb/DatabaseProvider'import { database } from './database'export default function App() {  return (    <DatabaseProvider database={database}>      {/* Your app content */}    </DatabaseProvider>  )}

Using WatermelonDB

Creating Records

import { useDatabase } from '@nozbe/watermelondb/hooks'function CreatePost() {  const database = useDatabase()  const createPost = async () => {    await database.write(async () => {      await database.get('posts').create((post) => {        post.title = 'My First Post'        post.body = 'Hello WatermelonDB!'      })    })  }  return (    <Button onPress={createPost} title="Create Post" />  )}

Querying Records

import { withDatabase } from '@nozbe/watermelondb/DatabaseProvider'import withObservables from '@nozbe/with-observables'function PostsList({ posts }) {  return (    <FlatList      data={posts}      renderItem={({ item }) => (        <Text>{item.title}</Text>      )}    />  )}const enhance = withObservables([], ({ database }) => ({  posts: database.get('posts').query().observe()}))export default withDatabase(enhance(PostsList))

Best Practices

  1. Batch Operations: Use batch operations when performing multiple writes:
await database.write(async () => {  await database.batch(    database.get('posts').prepareCreate(post => {      post.title = 'Post 1'    }),    database.get('posts').prepareCreate(post => {      post.title = 'Post 2'    })  )})
  1. Error Handling: Always wrap database operations in try-catch blocks:
try {  await database.write(async () => {    // database operations  })} catch (error) {  console.error('Database operation failed:', error)}
  1. Relationships: Define relationships between models using associations:
import { associations } from '@nozbe/watermelondb/Model'class Post extends Model {  static associations = associations([    'comments',    'author',  ])}

Common Issues and Solutions

1. Schema Migration

When updating your schema, create migrations:

import { schemaMigrations } from '@nozbe/watermelondb/Schema/migrations'const migrations = schemaMigrations({  migrations: [    {      toVersion: 2,      steps: [        // Migration steps      ],    },  ],})

2. Performance Optimization

  • Use lazy.load() for large relationships
  • Implement pagination using query().limit(20)
  • Use appropriate indexes in your schema

Conclusion

WatermelonDB is a powerful tool for building offline-first applications in React Native. By following this setup guide, you've learned how to:

  • Install and configure WatermelonDB
  • Set up your database schema and models
  • Perform basic CRUD operations
  • Handle relationships and migrations
  • Implement best practices for optimal performance

Remember to always refer to the official documentation for more detailed information and advanced features.


For more information about using WatermelonDB with TypeScript, advanced queries, or specific use cases, feel free to check out the official documentation or reach out to the community.