Using Realm from npm on Electron JS app - realm

I am trying to use Realm imported with NPM but it fails.
I am using the Realm example for JavaScript:
const Realm = require('realm');
// Define your models and their properties
const CarSchema = {
name: 'Car',
properties: {
make: 'string',
model: 'string',
miles: {type: 'int', default: 0},
}
};
const PersonSchema = {
name: 'Person',
properties: {
name: 'string',
birthday: 'date',
cars: 'Car[]',
picture: 'data?' // optional property
}
};
Realm.open({schema: [CarSchema, PersonSchema]})
.then(realm => {
// Create Realm objects and write to local storage
realm.write(() => {
const myCar = realm.create('Car', {
make: 'Honda',
model: 'Civic',
miles: 1000,
});
myCar.miles += 20; // Update a property value
});
// Query Realm for all cars with a high mileage
const cars = realm.objects('Car').filtered('miles > 1000');
// Will return a Results object with our 1 car
cars.length // => 1
// Add another car
realm.write(() => {
const myCar = realm.create('Car', {
make: 'Ford',
model: 'Focus',
miles: 2000,
});
});
// Query results are updated in realtime
cars.length // => 2
})
.catch(error => {
console.log(error);
});
And this is the error it throws:
Uncaught Error: Cannot find module
'[path]/node_modules/realm/compiled/electron-v2.0_darwin_x64/realm.node'
at Module._resolveFilename (module.js:543:15)
at Function.Module._resolveFilename ([path]/node_modules/electron/dist/Electron.app/Contents/Resources/electron.asar/common/reset-search-paths.js:35:12)
at Function.Module._load (module.js:473:25)
at Module.require (module.js:586:17)
at require (internal/module.js:11:18)
at Object. ([path]/node_modules/realm/lib/index.js:102:28)
at Object. ([path]/node_modules/realm/lib/index.js:133:3)
at Module._compile (module.js:642:30)
at Object.Module._extensions..js (module.js:653:10)
at Module.load (module.js:561:32)
Thank you so much for help.

Welcome to SO!
What happens is that electron specifies its own environment, while realm runtime loads its binaries based on this currently running environment.
However, when installing realm with npm, we fetch the binaries corresponding to the environment at the time of install, i.e. our node engine.
Therefore when running electron in dev mode, realm does not find the binary corresponding to the electron environment.
The usual workaround is to use the electron-builder package and run its install-app-deps command, which will install the appropriate binaries for the electron target environment.
It is usually recommended to make it an automatic script in your package.json file:
To ensure your native dependencies are always matched electron version, simply add script :
"scripts": {
"postinstall": "electron-builder install-app-deps"
}
…so that it get run whenever you install a new package.

Related

Vue 3 Vite Pinia Unit Testing - TypeError: [Function] is not a spy or a call to a spy! ONLY when running Coverage

In my Vue 3 (using Vite and vi-test) app I am using Pinia and I've written some unit basic tests which run ok when I run
npm run test:unit
but when I run
npm run coverage
I get test errors:
TypeError: [Function] is not a spy or a call to a spy!
Anyone know why one would work but not the other?
This is my script setup in package.json:
"test:unit": "vitest --environment jsdom",
"coverage": "vitest run --coverage",
Here's an example of a test - this will run fine with the first command but with the second command will give the above error on the expect(store.clearCheckedData) line
describe("ContactBook", () => {
let mockProps = {};
let wrapper:any;
beforeEach(() => {
wrapper = render(ContactBook, {
props: mockProps,
global: {
components: {ProgressSpinner,Button,InputText,BaseButton},
plugins: [PrimeVue,
createTestingPinia({
initialState: {contact:{
mockRegistrationData: mockRegistrationData,
loading: false,
}},
stubActions: false,
createSpy: vi.fn,
fakeApp:true
}),
],
},
});
setActivePinia(createPinia());
});
afterEach(() => {
cleanup();
});
it("when Year / Reg Group tab is clicked, registrations component is rendered", async() => {
const button = screen.getByText('Year / Reg Group')
await userEvent.click(button);
const store = useContactBookStore();
expect(store.clearCheckedData).toHaveBeenCalledTimes(1) // ERROR ON THIS LINE
expect(store.fetchRegistrationData).toHaveBeenCalledTimes(2)
wrapper.getByTestId("registrations-component")
});

Ionic Sqlite not running on chrome

import { Component } from '#angular/core';
import { NavController } from 'ionic-angular';
import { SQLite, SQLiteObject } from '#ionic-native/sqlite';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
username='name';
items = [];
constructor(public navCtrl: NavController, private sqlite: SQLite) {
}
save()
{
alert();
this.sqlite.create({
name: 'data.db',
location: 'default'
})
.then((db: SQLiteObject) => {
//data insert section
db.executeSql('CREATE TABLE IF NOT EXISTS usernameList(id INTEGER PRIMARY KEY AUTOINCREMENT,name)', {})
.then(() => alert('Executed SQL'))
.catch(e => console.log(e));
//data insert section
db.executeSql('INSERT INTO usernameList(name) VALUES(?)', [this.username])
.then(() => alert('Executed SQL'))
.catch(e => console.log(e));
//data retrieve section
db.executeSql('select * from usernameList', {}).then((data) => {
alert(JSON.stringify(data));
//alert(data.rows.length);
//alert(data.rows.item(5).name);
this.items = [];
if(data.rows.length > 0) {
for(var i = 0; i < data.rows.length; i++) {
//alert(data.rows.item(i).name);�
this.items.push({name: data.rows.item(i).name});
}
}
}, (err) => {
alert('Unable to execute sql: '+JSON.stringify(err));
});
})
.catch(e => alert(JSON.stringify(e)));
}
}
Why I am not able to test my code on broswe
I even try using ionic cordova run browser
This is my console error
OPEN database:
data.db cordova.js:1003 Error: exec proxy not found for
:: SQLitePlugin :: close cordova.js:1003 Error: exec proxy not found
for :: SQLitePlugin :: open
plugins/cordova-sqlite-storage/www/SQLitePlugin.js:196 OPEN database:
data.db FAILED, aborting any pending transactions
plugins/cordova-sqlite-storage/www/SQLitePlugin.js:174 OPEN database:
data.db cordova.js:1003 Error: exec proxy not found for ::
SQLitePlugin :: close cordova.js:1003 Error: exec proxy not found for
:: SQLitePlugin :: open
plugins/cordova-sqlite-storage/www/SQLitePlugin.js:196 OPEN database:
data.db FAILED, aborting any pending transactions
Mysql doesnot support on ionic for testing on browser. Cordova doesnot support it. You need to test in native app
SQLite is not meant to be used on non-"native" builds of your Ionic app:
https://ionicframework.com/docs/native/sqlite/ - see the platforms listed there and there is no "browser" as supported platform.
To test it you should run your app on a device via something like:
ionic cordova run android
Depending on your use case & your requirements for local persistence sometimes it make sense to use Ionic Storage: https://ionicframework.com/docs/storage/ which can use sqlite and can "fallback" / use another type of persistence that is supported by a browser (websql, indexeddb). In this case you can develop and test your app in browser using "ionic serve" and then later on validate that it also works fine on a real device.

Testing onUpdate results in TypeError: Cannot read property 'val' of undefined

I have recently migrated my Firebase Functions from beta to 1.0.2 and in the process wrote a bunch of unit tests using the new Firebase Test SDK for Cloud Functions. Some of my functions are responsible for mirroring data from Realtime to Firestore and as such I have used the onUpdate() Realtime Database trigger which provides change and context objects. My issue is, in testing these I get the error TypeError: Cannot read property 'val' of undefined because the after and before properties of the change object are undefined. These functions work when deployed, it's only during testing that this error crops up. One of the functions showing this issue is:
exports.mirrorTransactionUpdates = functions.database.ref("transactions/{id}").onUpdate((change, context) => {
return firestore.collection("transactions").doc(context.params.id).set(change.after.val());
});
and the unit test is:
describe("mirrorTransactionUpdates", () => {
it("should update transactions in firestore", () => {
const data = {date: 1};
const snapshot = test.database.makeDataSnapshot(data, "transactions/test_transaction_id");
return test.wrap(activeFunctions.mirrorTransactionUpdates)(snapshot, {
params: {id: "test_transaction_id"}
}).then(() => {
return firestore.collection("transactions").doc("test_transaction_id").get()
.then(mirroredDoc => {
assert.deepEqual(mirroredDoc.data(), data);
});
});
});
});
I cannot find anywhere why the change.before and change.after are not defined when unit testing. I also do not see anywhere in the docs where I can/have to define them myself. It should be noted that this also happens with the onWrite() event handler. Any help would be greatly appreciated!
I am using firebase-admin 5.11.0 and firebase-functions 1.0.2

Log 'jsonPayload' in Firebase Cloud Functions

TL;DR;
Does anyone know if it's possible to use console.log in a Firebase/Google Cloud Function to log entries to Stack Driver using the jsonPayload property so my logs are searchable (currently anything I pass to console.log gets stringified into textPayload).
I have a multi-module project with some code running on Firebase Cloud Functions, and some running in other environments like Google Compute Engine. Simplifying things a little, I essentially have a 'core' module, and then I deploy the 'cloud-functions' module to Cloud Functions, 'backend-service' to GCE, which all depend on 'core' etc.
I'm using bunyan for logging throughout my 'core' module, and when deployed to GCE the logger is configured using '#google-cloud/logging-bunyan' so my logs go to Stack Driver.
Aside: Using this configuration in Google Cloud Functions is causing issues with Error: Endpoint read failed which I think is due to functions not going cold and trying to reuse dead connections, but I'm not 100% sure what the real cause is.
So now I'm trying to log using console.log(arg) where arg is an object, not a string. I want this object to appear in Stack Driver under the jsonPayload but it's being stringified and put into the textPayload field.
It took me awhile, but I finally came across this example in firebase functions samples repository. In the end I settled on something a bit like this:
const Logging = require('#google-cloud/logging');
const logging = new Logging();
const log = logging.log('my-func-logger');
const logMetadata = {
resource: {
type: 'cloud_function',
labels: {
function_name: process.env.FUNCTION_NAME ,
project: process.env.GCLOUD_PROJECT,
region: process.env.FUNCTION_REGION
},
},
};
const logData = { id: 1, score: 100 };
const entry = log.entry(logMetaData, logData);
log.write(entry)
You can add a string severity property value to logMetaData (e.g. "INFO" or "ERROR"). Here is the list of possible values.
Update for available node 10 env vars. These seem to do the trick:
labels: {
function_name: process.env.FUNCTION_TARGET,
project: process.env.GCP_PROJECT,
region: JSON.parse(process.env.FIREBASE_CONFIG).locationId
}
UPDATE: Looks like for Node 10 runtimes they want you to set env values explicitly during deploy. I guess there has been a grace period in place because my deployed functions are still working.
I ran into the same problem, and as stated by comments on #wtk's answer, I would like to add replicating all of the default cloud function logging behavior I could find in the snippet below, including execution_id.
At least for using Cloud Functions with the HTTP Trigger option the following produced correct logs for me. I have not tested for Firebase Cloud Functions
// global
const { Logging } = require("#google-cloud/logging");
const logging = new Logging();
const Log = logging.log("cloudfunctions.googleapis.com%2Fcloud-functions");
const LogMetadata = {
severity: "INFO",
type: "cloud_function",
labels: {
function_name: process.env.FUNCTION_NAME,
project: process.env.GCLOUD_PROJECT,
region: process.env.FUNCTION_REGION
}
};
// per request
const data = { foo: "bar" };
const traceId = req.get("x-cloud-trace-context").split("/")[0];
const metadata = {
...LogMetadata,
severity: 'INFO',
trace: `projects/${process.env.GCLOUD_PROJECT}/traces/${traceId}`,
labels: {
execution_id: req.get("function-execution-id")
}
};
Log.write(Log.entry(metadata, data));
The github link in #wtk's answer should be updated to:
https://github.com/firebase/functions-samples/blob/2f678fb933e416fed9be93e290ae79f5ea463a2b/stripe/functions/index.js#L103
As it refers to the repository as of when the question was answered, and has the following function in it:
// To keep on top of errors, we should raise a verbose error report with Stackdriver rather
// than simply relying on console.error. This will calculate users affected + send you email
// alerts, if you've opted into receiving them.
// [START reporterror]
function reportError(err, context = {}) {
// This is the name of the StackDriver log stream that will receive the log
// entry. This name can be any valid log stream name, but must contain "err"
// in order for the error to be picked up by StackDriver Error Reporting.
const logName = 'errors';
const log = logging.log(logName);
// https://cloud.google.com/logging/docs/api/ref_v2beta1/rest/v2beta1/MonitoredResource
const metadata = {
resource: {
type: 'cloud_function',
labels: {function_name: process.env.FUNCTION_NAME},
},
};
// https://cloud.google.com/error-reporting/reference/rest/v1beta1/ErrorEvent
const errorEvent = {
message: err.stack,
serviceContext: {
service: process.env.FUNCTION_NAME,
resourceType: 'cloud_function',
},
context: context,
};
// Write the error log entry
return new Promise((resolve, reject) => {
log.write(log.entry(metadata, errorEvent), (error) => {
if (error) {
return reject(error);
}
resolve();
});
});
}
// [END reporterror]

Firebase Cloud Functions "admin.messaging(...).send is not a function"

I have a function in Firebase Functions service that send any FCM.
I would to use admin.messaging().send() function, like this reference guide, but I got this error while function is triggered, not during deploy:
TypeError: admin.messaging(...).send is not a function
at exports.sendChatNotification.functions.database.ref.onCreate.event (/user_code/lib/index.js:113:30)
at Object.<anonymous> (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:59:27)
at next (native)
at /user_code/node_modules/firebase-functions/lib/cloud-functions.js:28:71
at __awaiter (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:24:12)
at cloudFunction (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:53:36)
at /var/tmp/worker/worker.js:700:26
at process._tickDomainCallback (internal/process/next_tick.js:135:7)
I can see this error in Functions->Log inside Firebase console.
That's my function code:
exports.sendChatNotification = functions.database.ref('/messages').onCreate(event => {
var message = {
data: {
title: 'title',
body: 'body',
},
apns: {
header: {
'apns-priority': '10',
'apns-expiration':'0'
},
payload: {
aps: {
sound: 'default',
'content-available':'1'
}
}
},
android: {
ttl: 60*1000,
priority: 'high'
},
topic: 'mytopic'
};
return admin.messaging().send(message);
});
If I use admin.messaging().sendToTopic() and (changing the message structure) it works fine. It seems Firebase doesn't support its own API.
I deploy this using Firebase tools, with command line "firebase deploy".
I have updated firebase-tools and firebase-functions and firebase-admin in my functions project.
The send() function was added in firebase-admin 5.9.0. If you want to use it, you should run npm install firebase-admin#latest in your functions folder to install the latest version. At the time of this writing, the latest version is 5.9.1.

Resources