sqlitecloud / sqlitecloud-js

Javascript drivers for SQLiteCloud
https://sqlitecloud.github.io/sqlitecloud-js/
MIT License
16 stars 0 forks source link

React native / driver expects node-specific modules, breaks in React Native #109

Closed jacobprall closed 2 months ago

jacobprall commented 3 months ago

Before I describe the issues that I ran into when working with React Native with and without Expo, I will share how I was able to connect to my SQLite Cloud database using Expo. This will help provide some context for the issue with React Native.

Solution for connection to SQLite Cloud with Expo

I was able to connect to my SQLite Cloud database using Expo by passing an object to the Database instance where I specified that I wanted to use a web socket to connect.

{
   connectionstring: '<connection-string>',
   usewebsocket: true,
}

Issue I ran into when working with Expo before specifying that I wanted to connect via web socket

Previously to passing the object with the connection string to the Database instance and specifying that I wanted to use a web socket I ran into the following issue when running new Database('<connection-string>'). I got a console warning TypeError: tls.connect is not a function (it is undefined) when running the application and trying to connect to the SQLite Cloud database.

I followed the stack trace and logged the value of tls in the @sqlitecloud/drivers/lib/drivers/connection-tls.js file. The value of tls that is logging is {"default": {}}. Interestingly when running the app, the app worked on web but it didn’t work when using an ios Simulator or on my iphone. Here's a video that I created when I first ran into the issue.

Cause of the error

I did some research and it seems some Node core modules such as tls, and http, aren’t automatically available in React Native. However our JS client assumes that they'll be available.

Issue when working with React Native without Expo

When I tried to set up a React Native app without Expo I ran into an Invalid connection string error because url parsing logic failed in React Native. I followed the stack trace to @sqlitecloud/drivers/lib/drivers/utilities.js to the parseconnectionstring function. I added some console.logs to debug and noticed that the URL class seems to behave differently in React Native. In React Native, we try to execute the statement url.searchparams.forEach, but url.searchparams isn’t an array in React Native instead is an object {"_searchParams": []} so it doesn’t have a forEach method. In contrast, when I ran the following code in my browser console, it was clear that url.searchparams is an array in the browser.

In short, I wasn’t able to connect to the database in React Native. I tried connecting both ways 1. passing the connection string to the Database instance and 2. passing an object to the Database instance with the connection string and the usewebsocket:true property.

Gioee commented 2 months ago

Fixed websockets issue in: https://github.com/sqlitecloud/sqlitecloud-js/commit/7ca1d9d3f026a89b11b56d1fdbb5f54cf4d4160c, https://github.com/sqlitecloud/sqlitecloud-js/commit/7ee0f08ec18f419915dc1331229449aaa554d030 and https://github.com/sqlitecloud/sqlitecloud-js/commit/bc322b20423999dc5d5f9ea21afc206409a03808 Fixed tis issue in: https://github.com/sqlitecloud/sqlitecloud-js/commit/b1bd065eb5d1b7e2a414bbf23af6e9be3798ef4b, https://github.com/sqlitecloud/sqlitecloud-js/commit/03c2bab277622abb65bb55ebd7c780d100785210 and https://github.com/sqlitecloud/sqlitecloud-js/commit/887f6ccf3210f1e25db0b83736a109d39cfa3931