Nozbe / WatermelonDB

🍉 Reactive & asynchronous database for powerful React and React Native apps ⚡️
https://watermelondb.dev
MIT License
10.61k stars 599 forks source link

Warnings Record ... is cached, but full raw object was sent over the bridge #1675

Open LukasMod opened 1 year ago

LukasMod commented 1 year ago

Hey, when I do a refetch of data to a list which is observed withObservables, and each element of the list also observes its changes, the action itself looks ok. The list elements update and rerender quickly.

Refetch in the application involves downloading new data from the api, cleaning all records, adding new records after some transformations and adding some information from redux. I execute same function when app starts and there is no warnings, only when I execute it more times.

Looks something like that:

const cars: Collection<CarDB> = database.collections.get(TableSchema.CARS);
const queryCars = async () => await cars.query().fetch();

const refetchCars = async ({ newCars, favoriteCars }) => {
    try {
        await database.write(async () => {
            // Delete current cars
            const allRecords = await queryCars();
            const deletedRecords = allRecords.map(record => record.prepareDestroyPermanently());

            // Add new cars and car categories
            const newRecords = await Promise.all(
                newCars.map(async car => {
                  const carCategory = await database.collections
                            .get<CarCategoryDB>(TableSchema.CAR_CATEGORIES)
                            .find(car.carCategoryId);

                    return cars.prepareCreate(item => {
                        item._raw.id = car.id;
                        item.name = car.name;
                        item.isFavorite = favoriteCars.includes(car.id);
                        item.carCategory.set(carCategory);

                    });
                }),
            );

            // Delete and new records in single batch, to avoid empty state
            database.batch([...deletedRecords, ...newRecords]);
        });
    } catch (e) {
        console.log('[ERROR] insertCars', e);
    }
};

On the other hand, I get a warning for each element with the description: "Record <...> is cached, but full raw object was sent over the bridge".

I found such a thread where you mention not to worry about this: https://github.com/Nozbe/WatermelonDB/issues/1285#issuecomment-1406727547

I found this comment in watermelon's code inside @nozbe/watermelondb/src/Collection/RecordCache.js

This may legitimately happen if we previously got ID without a record and we cleared
adapter-side cached record ID maps to recover

In my case, it's still more than 200 warnings. 1 Could you explain a little more about this? How to understand this warning, is it something wrong or depends on situation?

  1. Why does it appear?
  2. How to avoid it?
  3. If it's something not to worry about, how to disable these warnings? LogBox does not disable warnings inside console anymore: LogBox.ignoreLogs([/is cached, but full raw object was sent over the bridge$/]);
SHIKHER09 commented 1 year ago

can I work on it ??

LukasMod commented 1 year ago

@SHIKHER09 If you mean could you work on the exact code, then unfortunately not, because this is a simplified example from a commercial application.

LukasMod commented 1 year ago

I can add, that using navigation.push instead of navigation.navigate (inside some nested stacks) does the same with multiple warnings inside console. Maybe that will help.

LukasMod commented 1 year ago

I commented out this log messages (on iOS it was too many lines in console). Patch file below. But it's not a solution, so I'm not closing issue.

@nozbe+watermelondb+0.27.0.patch

diff --git a/node_modules/@nozbe/watermelondb/Collection/RecordCache.js b/node_modules/@nozbe/watermelondb/Collection/RecordCache.js
index efedd6d..b359ada 100644
--- a/node_modules/@nozbe/watermelondb/Collection/RecordCache.js
+++ b/node_modules/@nozbe/watermelondb/Collection/RecordCache.js
@@ -85,7 +85,7 @@ var RecordCache = /*#__PURE__*/function () {
     if (cachedRecord) {
       // This may legitimately happen if we previously got ID without a record and we cleared
       // adapter-side cached record ID maps to recover
-      warnIfCached && _logger.default.warn("Record ".concat(this.tableName, "#").concat(cachedRecord.id, " is cached, but full raw object was sent over the bridge"));
+      // warnIfCached && _logger.default.warn("Record ".concat(this.tableName, "#").concat(cachedRecord.id, " is cached, but full raw object was sent over the bridge"));
       return cachedRecord;
     }
PEZO19 commented 1 year ago

@LukasMod I have a similar issue. WARN exists if the navigation happens inside a setTimeout, but does not if it is not (so it is a "sync" call). Do you have something similar?

// WARN as a whole
setTimeout(()=>{
  navigation.navigate(...) // if solely exists, no WARN
}, 0)
LukasMod commented 1 year ago

@PEZO19 Not navigation, but this could be something. My refresh is combined with InteractionManager.runAfterInteractions, and based on that result (from InteractionManager), it renders component connected to DB.

PEZO19 commented 5 months ago

For temporary purposes one might use the one and ugly in index.js 🙃

if (DEV.suppress_wm_cache_warn) {
  const originalWarn = console.warn;
  console.warn = (message, ...args) => {
    if (!message.includes('is cached, but full raw object was sent over the bridge')) {
    originalWarn(message, ...args);
  }
};