You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在React Native中结合Realm与MySQL实现离线存储及在线同步?

Hey there! Let's walk through how to set up Realm for offline storage in your React Native app and sync those local changes with your MySQL-backed web app. I’ve put together a practical, step-by-step approach that should fit your use case:

1. Get Realm Up and Running in React Native

First, install the necessary packages:

npm install realm @realm/react

Next, define your Realm data models. It’s a good idea to add fields that help with sync—like syncStatus (to track if an item needs to be sent to the server) and lastModified (for conflict resolution). Here’s an example model for a hypothetical "Task" entity:

import { Realm } from 'realm';

class Task extends Realm.Object {
  static schema = {
    name: 'Task',
    properties: {
      id: 'string', // Match the ID used in your MySQL database
      title: 'string',
      completed: 'bool',
      syncStatus: { type: 'string', default: 'pending' }, // 'pending' | 'synced' | 'failed'
      lastModified: 'date',
    },
    primaryKey: 'id',
  };
}

Initialize your Realm instance (usually in a context or a dedicated service file):

const realm = await Realm.open({
  schema: [Task],
  // Enable encryption if you're storing sensitive data
  // encryptionKey: new Uint8Array(64),
});
2. Handle Offline CRUD Operations

All user actions should first modify the local Realm database. This ensures the app works smoothly offline. For example:

  • Create/Update: Write to Realm and mark the item as pending sync
const createOrUpdateTask = async (taskData) => {
  realm.write(() => {
    realm.create('Task', {
      ...taskData,
      syncStatus: 'pending',
      lastModified: new Date(),
    }, Realm.UpdateMode.Modified);
  });
};
  • Delete: Soft-delete (mark as deleted and pending sync) is better than hard-delete here—it lets the server know to remove the corresponding record too.
3. Build the Sync Bridge to MySQL

Realm doesn’t sync directly with MySQL, so you’ll need to use your web app’s API as an intermediary. Here’s how to structure this:

3.1 Design Sync API Endpoints

Add these endpoints to your web app (connected to MySQL):

  • POST /api/sync: Accepts batch changes (create/update/delete) from the React Native app
  • GET /api/sync/latest: Fetches the latest changes from MySQL since a specific timestamp (for pulling server updates to the app)

3.2 Implement Sync Logic

Create a sync function that runs when the app is online:

const syncPendingChanges = async () => {
  // Get all pending items from Realm
  const pendingTasks = realm.objects('Task').filtered('syncStatus = "pending"');
  
  if (pendingTasks.length === 0) return;

  try {
    // Send batch to your web API
    await fetch('https://your-web-app-domain.com/api/sync', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(Array.from(pendingTasks)),
    });

    // Mark items as synced if successful
    realm.write(() => {
      pendingTasks.forEach(task => {
        task.syncStatus = 'synced';
      });
    });
  } catch (error) {
    // Mark failed items for retry later
    realm.write(() => {
      pendingTasks.forEach(task => {
        task.syncStatus = 'failed';
      });
    });
    console.error('Sync failed:', error);
  }
};

3.3 Pull Server Updates

Don’t forget to fetch changes from the server to keep the local Realm in sync:

const pullLatestChanges = async (lastSyncTimestamp) => {
  const response = await fetch(`https://your-web-app-domain.com/api/sync/latest?since=${lastSyncTimestamp}`);
  const serverTasks = await response.json();

  realm.write(() => {
    serverTasks.forEach(task => {
      // Use modified update mode to avoid overwriting local pending changes
      realm.create('Task', task, Realm.UpdateMode.Modified);
    });
  });
};
4. Trigger Sync Based on Network State

Use React Native’s NetInfo to detect when the app goes online and trigger sync automatically:

import NetInfo from '@react-native-community/netinfo';

// Set up network listener when your app starts
NetInfo.addEventListener(state => {
  if (state.isConnected) {
    syncPendingChanges();
    // Pull changes from the last 24 hours as a starting point
    pullLatestChanges(new Date(Date.now() - 24*60*60*1000));
  }
});
5. Conflict Resolution Tips

Conflicts happen when both local and server modify the same item. Here’s how to handle them:

  • Timestamp Priority: Use the lastModified field—always keep the version with the later timestamp.
  • User Input: For critical data, prompt the user to choose which version to keep.
  • Version Numbers: Add a version field that increments on each update; the server rejects updates with outdated versions.
Quick Pro Tips
  • Test Offline Scenarios: Disable your device’s network, make changes, then re-enable to verify sync works.
  • Encrypt Realm: If you’re storing sensitive data, enable Realm encryption using a 64-byte key.
  • Incremental Sync: Only sync changes since the last sync time to reduce data transfer and improve performance.

内容的提问来源于stack exchange,提问作者Dalton Pablo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:48:40