Unable to connect to SQLite in React-Native - android

I have pre-defined sqlite database using DB Browser for SQLite. I have place the db file in the path root/android/app/src/main/assets/www/mysqlite.db, unfortunately I'm unable to
connect. Below are my versioning.
Samsung Galaxy Android 11,
"react-native-sqlite-storage": "^6.0.1",
"react": "17.0.2",
"react-native": "0.65.1",
"#react-navigation/native": "^6.0.4",
My script(I make it simplified):
import SQLite from 'react-native-sqlite-storage';
SQLite.DEBUG(true);
SQLite.enablePromise(false);
export const AppSignIn = (props) => {
const OpenDB = () => {
return new Promise((resolve, reject) => {
global.db = SQLite.openDatabase(
{
name: 'mysqlite.db',
createFromLocation: '~mysqlite.db',
},
() => {
console.log("Connection success!");
},
error => {
console.log(error);
reject();
});
resolve();
});
}
const ReadDB = () => {
return new Promise((resolve) => {
global.db.transaction(function (tx) {
tx.executeSql(
// The rest of the trx
);
resolve();
});
});
}
async function ConnectDB() {
return new Promise(async (resolve, reject) => {
await OpenDB()
.then(async () => {
await ReadDB()
.then(() => {
console.log('YEAY FINALLY');
resolve();
})
})
.catch((error) => {
console.log(error);
reject();
});
});
}
React.useEffect(() => {
(async () => {
await ConnectDB()
.then()
.catch();
})();
}, []);
}
The log writes:
LOG OPEN database: mysqlite.db
LOG SQLite.open({"name":"mysqlite.db","createFromLocation":"~mysqlite.db","dblocation":"nosync","assetFilename":"~mysqlite.db"})
LOG new transaction is waiting for open operation
LOG Phone connected? true, Server connected? true
LOG OPEN database: mysqlite.db failed, aborting any pending transactions
LOG [Error: Could not open database]
I have tried several ways but I'm unable to connect to it.
Move from www to assets folder directly. Uninstall app on phone and run again.
Remove SQLite.enablePromise(false);
react-native link react-native-sqlite-storage
cd android && ./gradlew clean
Follow step to opendatabase call

Try moving your file for android from root/android/app/src/main/assets/www/mysqlite.db -> root/android/app/src/main/assets/mysqlite.db

I finally able to run it on Samsung Galaxy with Android 11. I've tried on Redmi6 with Android 9 and it can run.
I've removing react-native.config.js which contain SQLite
module.exports = {
dependencies: {
"react-native-sqlite-storage": {
platforms: {
android: {
sourceDir: "../node_modules/react-native-sqlite-storage/platforms/android-native",
packageImportPath: "import io.liteglue.SQLitePluginPackage;",
packageInstance: "new SQLitePluginPackage()"
}
}
}
}
};
I also remove the import module import io.liteglue.SQLitePluginPackage; in MainApplication.java and the database finally open.
I'm not sure if this way are absolute. I hope it was temporary as it oppose the way from the tutorial.

Related

How to mock PermissionAndroid from react native

I'm building an android app using React-native and using PermissionsAndroid from react-native to get user permission.
import {PermissionsAndroid} from 'react-native'
Now i'm writing unit test and i need to verify the component behaviour based on the Permission.
hence i need to mock PermissionsAndroid.
Is there a way to do this?
jest.mock('react-native//Libraries/PermissionsAndroid/PermissionsAndroid', () => {
const PermissionsAndroid = jest.requireActual(
'react-native//Libraries/PermissionsAndroid/PermissionsAndroid',
);
console.log(PermissionsAndroid);
return {
...PermissionsAndroid,
check: jest.fn(() => new Promise(resolve => resolve(true))),
request: jest.fn(() => new Promise(resolve => resolve(true))),
};
});
This worked for me in 2022
jest.mock('react-
native//Libraries/PermissionsAndroid/PermissionsAndroid', () => {
return {
...jest.requireActual('react- native//Libraries/PermissionsAndroid/PermissionsAndroid'),
request: jest.fn(() => new Promise(resolve => resolve('granted')))
}
})
Because it is async you have to later on await it e.g. with react testing library const element = await findByText(...)
Simply mocking
jest.doMock('react-native', () => ({ PermissionsAndroid: {... did not work for me. Here is how I got it to work specifically mocking requestMultiple and check.
let fineLocationPermissionResult: String = PermissionsAndroid.RESULTS.GRANTED;
let courseLocationPermissionResult: String = PermissionsAndroid.RESULTS.GRANTED;
let fineLocationPermissionGranted = true;
let coarseLocationPermissionGranted = true;
const permissionsAndroidModule = jest.requireActual('react-native/Libraries/PermissionsAndroid/PermissionsAndroid.js');
jest.doMock('react-native/Libraries/PermissionsAndroid/PermissionsAndroid', () => ({
...permissionsAndroidModule,
requestMultiple: () => {
return {
[PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION]: fineLocationPermissionResult,
[PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION]: courseLocationPermissionResult,
};
},
check: () => {
return fineLocationPermissionGranted && coarseLocationPermissionGranted;
},
}));
I've included some of the variables I used in my tests to manipulate the results of the mock but essentially you need to mock the entire module path ('react-native/Libraries/PermissionsAndroid/PermissionsAndroid') and then include the rest of the module that you are not mocking via jest.requireActual.
Solution below:
jest.mock(
'react-native//Libraries/PermissionsAndroid/PermissionsAndroid',
() => ({
PermissionsAndroid: {
request: () => {
true;
},
check: () => {
true;
},
},
})
);
You can mock this from react-native directly, just like:
jest.doMock('react-native', () => ({
PermissionsAndroid: {
request: (permission: string) => {
//whatever you want
},
},
}))
Notice that you might see some issues with the components you are using for that unit test, i.e. it might show an error if you are using <View> from React Native and not mocking it. Given that case, you have to import <View> and then include it in your mock.
import { View } from 'react-native'
...
jest.doMock('react-native', () => ({
View,
PermissionsAndroid: {
request: (permission: string) => {
//whatever you want
},
},
}))

How do I use a prepopulated SQLite DB with Expo on Android?

I'm trying to use a prepopulated SQLite DB for my react native app. I'm using Expo and the downloadAsync() Function to load my DB from my assets folder. This works as expected on IOS, as I can load the DB and retrieve the data.
On Android however I just can't get this to work. The db file is there in the internal storage of my emulator, but every time I try to retrieve data, an error occurs since 'there is no such table'.
My guess is that SQLite doesn't properly search for my db but instead creates a new one, where my tables are obviously missing.
I've been trying for over 7 hours now, so I appreciate any kind of help.
Folder structure:
App.js
-assets
--db
---db.db
-src
--connection
---connectionClass
App.js
const App = () => {
const [dbLoaded, setDbLoaded] = useState(false);
if(!dbLoaded){
downloadDB().then((value) => setDbLoaded(value));
return <></>
} else {
return (
<Navigation/>
);
}
};
ConnectionClass.js
export const downloadDB = async () => {
await FileSystem.deleteAsync(`${FileSystem.documentDirectory}SQLite`, {idempotent : true});
await FileSystem.makeDirectoryAsync(`${FileSystem.documentDirectory}SQLite`, {intermediates: true });
return await FileSystem.downloadAsync(
Asset.fromModule(require('../../assets/db/WaKanji.db')).uri,
`${FileSystem.documentDirectory}SQLite/WaKanji.db`
).then(({status}) => {
if(status === 200){
return true
}
return false
}).catch(error => {
console.log('Err\n' + error);
return false;
});
};

deviceNotReady error : "Registration failed" react-native-twilio-programmable-voice

I am working on react native application and want to integrate the Phone masking feature like Uber do. I have choosen Twilio Phone Masking for this. I have used react-native-twilio-programmable-voice package.
I have integrated this using this link:: https://medium.com/#edzh1/create-a-twilio-voip-calls-in-a-react-native-app-35a729a9613d
I have done server setup successfully, using php. But getting error deviceNotReady error : "Registration failed". I have no idea what I am doing wrong here.
This is initial function I am calling here::
initTwilio = async () => {
const token = await this.getAuthToken();
if (Platform.OS === 'android') {
await this.getMicrophonePermission();
}
const success = await TwilioVoice.initWithToken(token);
if (success.initialized) {
TwilioVoice.addEventListener('deviceReady', () => {
this.setState({ twilioInited: true });
});
TwilioVoice.addEventListener('deviceNotReady', function (data) {
console.log('data', data) // getting error here
});
if (Platform.OS === 'ios') { //required for ios
TwilioVoice.configureCallKit({
appName: 'ReactNativeTwilioExampleApp',
});
}
}
};
getAuthToken = () => {
return fetch('https://myurl/accessToken.php', {
method: 'get',
})
.then(response => response.text())
.catch((error) => console.error(error));
}
Please help, and suggest me what I am doing wrong here.

bundle.js file gets deleted after file is already inside the cache on pwa

When i push my pwa to Heroku after some "close and reopen" the app, the bundle.js gets deleted from the cache storage inside the browser. So when i open the app it only shows a white screen. It only happens on Android with chrome.
my service worker:
CACHENAME = '2020-02-29 23:48:15.963115'
const CACHEASSETS = [
'./index.html',
'./main.css',
'./bundle.js',
'./sw.js',
'./manifest.json',
'./images',
'./static.json',
'./images/icons',
'./images/icons/icon-384x384.png',
'./images/icons/icon-96x96.png',
'./images/icons/icon-144x144.png',
'./images/icons/icon-72x72.png',
'./images/icons/icon-192x192.png',
'./images/icons/icon-128x128.png',
'./images/icons/icon-152x152.png',
'./images/icons/icon-512x512.png',
'./',
'./home',]
self.addEventListener('install', (e) => {
console.log('The service worker is being installed.');
e.waitUntil(
caches
.open(CACHENAME)
.then(cache => {
console.log("Service Worker: Caching Files");
cache.addAll(CACHEASSETS);
})
.then(() => self.skipWaiting())
);
});
self.addEventListener('activate', (e) =>{
console.log("Service Worker: Activated");
e.waitUntil(
caches.keys().then(cacheNames =>{
return Promise.all(
cacheNames.map(cache =>{
if(cache !== CACHENAME){
console.log("Service Worker: Clearing Old Cache",cache);
return caches.delete(cache);
}
})
)
})
)
})
self.addEventListener('fetch', (e) => {
console.log("Service Worker: Fetching", e);
if(e.request.clone().method === 'GET'){
e.respondWith(
caches.match(e.request).then((cachedResponse) =>{
return cachedResponse;
})
)
}
});
Here is the app: https://mysterious-anchorage-81982.herokuapp.com/
Test enviroment: Chrome 80.0.3987.117 on Android 9.

firebase dynamic link with react-navigation

I have followed this document https://rnfirebase.io/docs/v4.1.x/links/android and able to run adb shell am start -W -a android.intent.action.VIEW -d "https://abc123.app.goo.gl" com.myapp.superapp to start the app.
How can open a dynamic link https://abc123.app.goo.gl it open the VideoScreen and pass the contentparam
Video:{
screen : VideoScreen,
path:'wvc/:contentparam',
}
So I tried this when clicking https://abc123.app.goo.gl (dynamic link):
componentDidMount () {
Linking.getInitialURL().then((url) => {
console.log('Initial url is: ' + url);
}).catch(err => console.error('An error occurred', err));
}
However app opened but console.log given null
For some reason firebase.links().onLink((url) does not work in RNFB v6.
Here is a comment on this bug from one of RNFB maintainers
https://github.com/invertase/react-native-firebase/issues/3008
Use should use react native Link instead, as a temporary workaround:
https://facebook.github.io/react-native/docs/0.47/linking
Here is an example you can use:
useEffect(() => {
Linking.getInitialURL()
.then(url => {
if (url) {
console.log('Initial url is: ' + group);
}
})
.catch(err => console.error('An error occurred', err));
}, []);
You have to listen to firebase links
componentDidMount() {
const unsubscribe = firebase.links().onLink((url) => {
console.log('dynamic links', url)
// do navigate with url above
// you have to handle your self
});
}
componentWillUnmount() {
unsubscribe()
}
docs: https://rnfirebase.io/docs/v5.x.x/links/reference/links#onLink

Categories

Resources