Nozbe / WatermelonDB

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

[Question] Cordova Platform Support With SQLite #1098

Open a777med opened 3 years ago

a777med commented 3 years ago

Hello,

I would like to use WatermelonDB with a webview app. Like, Cordova or Capacitor. I specifically want the SQLite adapter. Is that possible? If not, could you guide me to the first steps to contributing toward adding this feature?

Thanks.

radex commented 3 years ago

Yes, it's possible to develop such a feature. Here is some general info about adapters: https://github.com/Nozbe/WatermelonDB/blob/master/docs-master/Implementation/Adapters.md

The best way to understand what it takes to develop a Cordova adapter is to peruse sqlite implementation: https://github.com/Nozbe/WatermelonDB/tree/master/src/adapters/sqlite — note that index.js and encode* are common for all implementations, but then there's a sqlite-node hookup (sqlite in node) as well as native iOS implementation: https://github.com/Nozbe/WatermelonDB/tree/master/native/ios/WatermelonDB , Android: https://github.com/Nozbe/WatermelonDB/tree/master/native/android/src/main/java/com/nozbe/watermelondb and C++: https://github.com/Nozbe/WatermelonDB/tree/master/native/shared

You could likely reuse both iOS and Android code and only replace the DatabaseBridge implementations from React Native to Cordova

stale[bot] commented 2 years ago

Is this still relevant? If so, what is blocking it? Is there anything you can do to help move it forward?

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.

riderx commented 1 year ago

Hey @radex i'm open-source maintainer of few capacitor plugins one feedback I get the most is about offline database, your solution seems perfect, how I can import your work in ios and android ? usually for my plugin I use cocoapods and graddle import for that. You can see that for my Capacitor purchase plugin who use RevenueCat SDK. Then I will do the bridge part as you for React Native and we are done :)

radex commented 1 year ago

@riderx This is the native side of React Native bridge: https://github.com/Nozbe/WatermelonDB/blob/master/native/ios/WatermelonDB/DatabaseBridge.m

and this is the JS side: https://github.com/Nozbe/WatermelonDB/blob/master/src/adapters/sqlite/makeDispatcher/index.native.js

Everything else should be more or less React Native agnostic, so if you contribute the missing bridging parts, you can make it work with capacitor/cordova/something else

riderx commented 1 year ago

@radex i was thinking to do a specific repo for capacitor plugin and import WatermelonDB in it, I'm not sure mixing both implementation are the best. Specialy since my understanding of React Native is very limited

radex commented 1 year ago

@riderx I have no clue how capacitor plugins look like, but I would not like to import another SDK to WatermelonDB repo. So yes, you'll probably want to make a separate repo for it.

Still, you might need to contribute some changes to Watermelon to make such an integration seamless and reliable. On native side, DatabaseBridge basically is just an RN-specific interface, but all Watermelon-specific logic is in DatababaseDriver. Just make sure that DatabaseDriver is set as public (exported) so that you can interact with it from another module.

For JS side, "dispatcher" is the abstraction for interacting with native implementations of sqlite. You'll see that there's a classic RN implementation, JSI RN implementation, and also node-sqlite implementation. So you need another one. But if it's gonna live in another package, you might need to make some changes to the SQLiteAdapter/dispatcher so that you can pass an external dispatcher, maybe something roughly like this:

import SQLiteAdapter from '@nozbe/watermelondb/xxxxx'
import { WatermelonDBSqliteCapacitorDispatcher } from 'xxxxx'

const dispatcher = your thing
const adapter = new SQLiteAdapter({ dispatcher, ... })
const db = new Database({ adapter, ... })
riderx commented 1 year ago

thank you so much for the enlightenment.

If you are curious, there is the template folder who is you when you generate a new capacitor plugin : https://github.com/ionic-team/create-capacitor-plugin/tree/main/assets/plugin-template

It's a bit like React Native, 3 folders for android, IOS and JS.

I think the way RevenueCat build his repo arch make a lot of sense, they publish android and IOS lib in 2 repo, and then use them in React Native/Cordova and unity, one repo each.

That would help me a lot if WatermelonDB was a Java lib and IOS lib, then i would just import it in both platforms.

I'm not sure to understand the concept of dispatcher.

in Capacitor plugin usually there are no much JS code.

Example of simple method in java

    @PluginMethod()
    public void echo(PluginCall call) {
        String value = call.getString("value");

        JSObject ret = new JSObject();
        ret.put("value", value);
        call.resolve(ret);
    }

and in JS the only things you will provide is the Typescript definition

export interface MyPluginPlugin {
  echo(options: { value: string }): Promise<{ value: string }>;
}

I could also make more in JS with custom implementation, for that i need to understand more your code.

You can see here a sqlite capacitor plugin : https://github.com/capacitor-community/sqlite

riderx commented 1 year ago

I made a base plugin with basic install of watermelondb in it : https://github.com/Cap-go/capacitor-watermelondb i need now to understand how to do create dispatcher and adapter

riderx commented 1 month ago

Coming back do the topic, @radex do you think we could move to a mono repo where RN, Capacitor, IOS and Android could have each a folder ?