RecordId was sent over the bridge, but it's not cached. I am getting this error a lot when trying to implement WatermelonDB. It seems to be that I can make a query but once I make another query on the same table it gives me that error.
Diagnostic error: Record ID touchpoints#42fkr0mf4etavdw3 was sent over the bridge, but it's not cached
at diagnosticError (blob:http://localhost:8081/47ca6aff-f1b8-40cc-832a-52c832920571:136779:17)
at invariant (blob:http://localhost:8081/47ca6aff-f1b8-40cc-832a-52c832920571:136754:48)
at RecordCache._cachedModelForId (blob:http://localhost:8081/47ca6aff-f1b8-40cc-832a-52c832920571:138849:32)
at RecordCache.recordFromQueryResult (blob:http://localhost:8081/47ca6aff-f1b8-40cc-832a-52c832920571:138840:23)
at blob:http://localhost:8081/47ca6aff-f1b8-40cc-832a-52c832920571:138833:24
at Array.map (<anonymous>)
at RecordCache.recordsFromQueryResult (blob:http://localhost:8081/47ca6aff-f1b8-40cc-832a-52c832920571:138832:23)
at Collection._callee3$ (blob:http://localhost:8081/47ca6aff-f1b8-40cc-832a-52c832920571:137243:103)
at tryCatch (blob:http://localhost:8081/47ca6aff-f1b8-40cc-832a-52c832920571:27304:19)
at Generator.invoke [as _invoke] (blob:http://localhost:8081/47ca6aff-f1b8-40cc-832a-52c832920571:27479:24)
give us more details: what platform, code sample, etc.
I am on RN 60.
Here is one of the spots it is failing.
const collection = await database.collections.get(table);
const records = await collection.query().fetch();
await database.action(async() => {
records.forEach(async(record: any) => await record.destroyPermanently());
});
The failure is happening on the query though. I am getting the error on the .query().fetch().
Is there an update on this? Could part of the problem be that I am observing on the table in a different component?
@arambrosius no update. This is an open source project -- I recommend that you put in some console.logs in the watermelon repo to try and track down why exactly the record was improperly cached.
I am still seeing this issue. I get this error if I observe on a table in a component or if I just fetch the data.
export const EnhancedAccountTouchpoints = withDatabase(
withObservables(['account'], ({ account, database }: DatabaseProps) => ({
touchpoints: database.collections
.get(Table.Touchpoints)
.query(Q.where('account_id', account.id))
.observe(),
}))(AccountTouchpoints),
);
This example gives me data for a specific account. This works the first time the component is loaded but as soon as I navigate away and come back to the same account I am getting the cache of recordId error. From what I can tell I have followed the docs exactly and there isn't any documentation about caching of the data or subscribing/unsubscribing from observing on queries.
export default withDatabase(withObservables([], ({ database }) => ({
blogs: database.collections.get('blogs').query().observe(),
}))(BlogList))
This is the example that is given in the watermelon docs. How do you suggest for me to resolve this so I can move forward? I would really like to use this package if possible but I am unable to get anything to load as of right now. The exception is thrown on .observe() and .fetch().
as soon as I navigate away and come back to the same account I am getting the cache of recordId error
@arambrosius If you are using react-native-navigation and passing a record through passProps then you will face this error.
RNN creates a deep clone of passProps before passing them to the new screen and therefore destroys any reference to the original items. This causes problem with WDB if you pass in a record since the record has a reference to its collection and it has reference to its record cache as record.collection._cache. So when RNN clones this record, a new Map instance is created for _cache and this causes the RecordId was sent over the bridge, but it's not cached error.
An easy fix is to pass only the record id and let the receiver screen load the record.
FYI I fixed another way this issue could appear here: https://github.com/Nozbe/WatermelonDB/pull/593
I have watched this message too.
E/ReactNativeJS(28949): '[AssetsInfo] DBCrud::findByJson() catch exception: ', { [Diagnostic error: Record ID AssetsInfo#0xd5cc3810197238b06f0f333b5cb2046e0c6ece9a was sent over the bridge, but it's not cached]
E/ReactNativeJS(28949): framesToPop: 2,
E/ReactNativeJS(28949): name: 'Diagnostic error',
E/ReactNativeJS(28949): line: 272531,
E/ReactNativeJS(28949): column: 26,
In my case, I use watermelon DB just as storage, not use the reactive feature. So I only use the _raw property and do operation on _raw object.
Bellow is the main API that I wrap base on the watermelon DB.
const mySchema = tableSchema({
name: 'AssetsInfo',
columns: [
// by default, each table has 'id' column of string type
...
{ name: 'decimals', type: 'number' },
{ name: 'rateUSD', type: 'number' },
{ name: 'version', type: 'string' },
],
})
class AssetsInfo extends Model {
static table = AssetsInfo;
// NO FIELDS, BECAUSE I DON'T OPERATION VIA MODEL.
}
...
async insert(newDoc) {
try{
let dataSet;
clear_private_field(newDoc);
(newDoc instanceof Array) ? dataSet = newDoc : dataSet = [newDoc];
await this.db.action(async ()=> {
let preparedDocs = [];
for (let i = 0; i < dataSet.length; i++) {
let _doc = dataSet[i];
const _docToAdd = await this.collection.prepareCreate(doc => {
// If insert raw document has id field, ensure it is of string type.
if(_doc.id === undefined || _doc.id === null) {
_doc.id = doc._raw.id
}else {
ensureDocIdType(_doc);
}
// _sanitizedRaw() is copy from this lib source folder.
doc._raw = _sanitizedRaw(_doc, this.collection.schema);
})
preparedDocs.push(_docToAdd)
}
await this.db.batch(...preparedDocs);
})
return newDoc;
}catch (e) {
console.error(`Failed insert doc to ${this.collection.schema.name}, error: `, e);
return [];
}
}
async findByJson(filterObj) {
ensureDocIdType(filterObj); // filterObj is an Json style object that follow the mongoDB style
let foundDocs = []
try {
let condSet;
condSet = convert(filterObj);
if(condSet) {
foundDocs = await this.collection.query(...condSet).fetch()
if(! (foundDocs instanceof Array)) {
console.log(`[${this.collection.schema.name}]DbCrud::findByJson} got no docs.` )
return []
}
foundDocs = foundDocs.map(doc => doc._raw)
}
}catch (e) {
console.error(`[${this.collection.schema.name}] DBCrud::findByJson() catch exception: `, e);
}
// delete _status and _changed field
if(foundDocs.length > 0) clear_private_field(foundDocs);
return foundDocs;
}
async update(id, newDoc) {
let retVal = 1;
id = ensureToString(id);
let doc = await this.collection.find(id).catch(e => {
console.log(`DBCrud::update(${id}) catch exception: `, e);
return 0
})
if(!doc) {
console.log(`DBCrud::update(${id}) no such document`);
return 0;
}
await this.db.action(async () => {
await doc.update(doc => {
clear_private_field(newDoc)
let _tempDoc = Object.assign(doc._raw, newDoc)
doc._raw = _sanitizedRaw(_tempDoc, this.collection.schema);
})
}).catch(e=>{
console.log(`DBCrud::update(${id}) catch exception: `, e);
retVal = 0;
})
return retVal
}
Is there anything wrong with my code?
Can this error message be ignore if unable to solve?
Also, in my case, not use reactive, are there configurations to tune? Thank a lot~