Search code examples
react-nativeexpo-gowatermelondbexpo-module

Expo Go watermelonDB through @skam22/watermelondb-expo-plugin: NativeModules.WMDatabaseBridge is not defined


Working on an Expo Go mobile app, and I'm looking to use WatermelonDB for database. I'm hoping to use the @skam22/watermelondb-expo-plugin package (as opposed to @morrowdigital/watermelondb-expo-plugin) to facilitate this. The errors I'm getting are after this paragraph. I have restarted the server, and am running npx expo start from the root directory of the app. Does anyone have any idea why my project is failing to load NativeModules.WMDatabaseBridge?

Android Bundling complete 5637ms
 ERROR  Diagnostic error: NativeModules.WMDatabaseBridge is not defined! This means that you haven't properly linked WatermelonDB native module. Refer to docs for instructions about installation (and the changelog if this happened after an upgrade)., js engine: hermes
 ERROR  Invariant Violation: "main" has not been registered. This can happen if:
* Metro (the local dev server) is run from the wrong folder. Check if Metro is running, stop it and restart it in the current project.
* A module failed to load due to an error and `AppRegistry.registerComponent` wasn't called., js engine: hermes

If I use npx expo run:android, I get a long list of errors consisting of The binary version of its metadata is 1.8.0, expected version is 1.6.0. and some Unresolved reference lines.

Steps I've taken:

  • Added in app.json (I removed the IOS part to make sure it wasn't causing the problem, as I'm testing on Android)
{ "expo" : {
  "plugins": [
    [
      "expo-build-properties",
      {
        "android": {
          "kotlinVersion": "1.6.10",
          "compileSdkVersion": 33,
          "targetSdkVersion": 33,
          "packagingOptions": {
            "pickFirst": [
              "**/libc++_shared.so"
            ]
          }
        }
      }
    ],
    "@skam22/watermelondb-expo-plugin"
  ]
}
  • Almost regular metro.config.js (@firebase/auth exists in my project, so config.resolver... line is for that)
const { getDefaultConfig } = require('expo/metro-config');

const config = getDefaultConfig(__dirname);
config.resolver.sourceExts.push('cjs');

module.exports = config;
  • Added plugin to babel.config.js
module.exports = function(api) {
  api.cache(true);
  return {
    presets: ['babel-preset-expo'],
    plugins: [['@babel/plugin-proposal-decorators', { legacy: true }]],
  };
};
  • Created database.js to setup the DB, and imported into App.js
const adapter = new SQLiteAdapter({
  schema,
  migrations,
  dbName: 'familytree',
  jsi: false,
  onSetUpError: error => { console.log(error); },
});

const database = new Database({
  adapter,
  modelClasses: [
    Family,
    FamilyMember,
    User,
  ],
});

export { database, adapter };
  • Added the following models:
// family.js
import { Model } from '@nozbe/watermelondb';
import { relation } from '@nozbe/watermelondb/decorators';

class Family extends Model {
  static table = 'families';
  static associations = {
    familyMembers: { type: 'belongs_to', foreignKey: 'family_id' },
  };

  @relation('family_members', 'family_id') familyMember;
}

export { Family };

// familyMember.js
import { Model } from '@nozbe/watermelondb';
import { relation } from '@nozbe/watermelondb/decorators';

class FamilyMember extends Model {
  static table = 'family_members';
  static associations = {
    family: { type: 'belongs_to', key: 'family_id' },
    user: { type: 'belongs_to', key: 'user_id' },
  };

  @relation('families', 'family_id') family;
  @relation('users', 'user_id') user;
}

export { FamilyMember };

// user.js
import { Model } from '@nozbe/watermelondb';
import { field, relation } from '@nozbe/watermelondb/decorators';

class User extends Model {
  static table = 'users';
  static associations = {
    familyMembers: { type: 'belongs_to', foreignKey: 'user_id' },
  };

  @field('name') name;
  @field('created_at') createdAt;
  @field('updated_at') updatedAt;

  @relation('family_members', 'user_id') familyMember;

}

export { User };

Solution

  • there's a version mismatch with your android gradle and kotlin.

    you can solve it in a few steps:

    1. In your home directory, delete your .gradle folder to start with a clean cache
    2. In your project directory, delete your android folder
    3. In your project directory, update your app.json to use kotlinVersion 1.8.10:
    {
       "expo": {
           "plugins": [
               [
                   "expo-build-properties",
                   {
                       "android": {
                           "kotlinVersion": "1.8.10",
                       }
                   }
               ]
           ]
       }
    }