Skip to content

[Onyx] Native Onyx.merge persists different values to SQLite than the cache #105485

Open

Description

@MelvinBot

Problem

On native, Onyx.merge can write a different value to SQLite than the one it keeps in the cache. After an app restart, Onyx loads the SQLite value, so the app can show stale data.

This happens in two cases:

  1. New key with null properties. For a key that has no stored value yet, null should remove the property. The cache drops it, but SQLite stores the null. The SQLite upsert applies JSON_PATCH only to existing rows, so a new row stores the merge delta unchanged.
  2. Batched null reset. When a merge batch for a key contains null followed by a new object, SQLite keeps the old fields instead of replacing the value.
await Onyx.merge('test', {keep: true, remove: null});

// Cache:  {keep: true}
// SQLite: {keep: true, remove: null}

Reproduction

In an initialized native Onyx development build with two registered test keys:

  1. Set the first test key to {old: true}.
  2. Queue a merge batch for that key containing null followed by {new: true}.
  3. Export persisted state with Onyx.exportState().
  4. Merge {nested: {keep: true, remove: null}} into the previously unused second key.
  5. Export persisted state again.

Expected: The first key contains only {new: true}, and the second key contains only {nested: {keep: true}}.

Actual: SQLite keeps the old fields for the first key and keeps remove: null for the second key.

Fix

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions