ionic 3 : Can't resolve all parameters for SQLiteObject: (?) - sqlite

I'm using Ionic 3 SQLite native plugin from Here(Ionicframework.com), and Here's my constructor code :
constructor(public navCtrl: NavController,
public menu: MenuController,
translate: TranslateService,
private tts: TextToSpeech,
private sqlite: SQLite) {
this.sqlite.create({
name: 'data.db',
location: 'default'
}).then((db: SQLiteObject) => {
db.executeSql('create table IF NOT EXISTS `localflags`(`flag1` VARCHAR(10),`flag2` VARCHAR(10),`flag3` VARCHAR(10), `flag4` VARCHAR(10));', {})
.then(() => console.log('Table created!!!'))
.catch(e => console.log(e));
}).catch(e => console.log(e));
}
So, when I run it on device using "ionic cordova run android -lc" it give me this error,
Can't resolve all parameters for SQLiteObject: (?)
This code is from the ionic native documentation. This is very basic code, and I'm new to this, so I can't figure out what's wrong with this.
Any help will be appreciated. And if someone can point me to the Ionic 3 SQLite tutorials , that will be great. Thanks in Advance.

Actually, the case was, I had Done import { SQLite, SQLiteObject } from '#ionic-native/sqlite'; this in my ts file, So I thought both SQLite and SQLiteObject are needed to imported in app.module.ts file, but after reading this answer, I removed SQLiteObject from app.module.ts file and also removed injection of SQLite from the constructor and it worked.
Hope this helps someone.

I think you have to add "/ngx" on your import line
import { SQLite, SQLiteObject } from '#ionic-native/sqlite/ngx';
Besides, you don't have to add SQLiteObject in the providers array of app.module.ts file

Related

AngularFire#7.1.1: NullInjectorError: No provider for Firestore

I'm getting the following error message with my Angular 12 app: NullInjectorError: No provider for Firestore!
Firestore is initialized both the old and the new way in my lazy loaded admin.module.ts
import { connectFirestoreEmulator, getFirestore, provideFirestore } from "#angular/fire/firestore";
import { AngularFirestoreModule } from "#angular/fire/compat/firestore";
...
imports: [
AngularFirestoreModule,
provideFirestore(() => {
const firestore = getFirestore();
if (!environment.production) {
connectFirestoreEmulator(firestore, "localhost", 8080);
}
return firestore;
}),
]
Also setting up Firebase both ways in my app.module.ts
import { provideFirebaseApp, initializeApp } from "#angular/fire/app";
import { AngularFireModule } from "#angular/fire/compat";
...
imports: [
AngularFireModule.initializeApp(environment.firebase),
provideFirebaseApp(() => initializeApp(environment.firebase)),
]
And finally, using Firestore in one of my services, (let's call it foo.service.ts) that is being provided by my admin.module.ts
import { Firestore } from "#angular/fire/firestore";
...
export class ScanRepositoryService {
constructor(private firestore: Firestore) {}
}
From what I can tell, I'm following the AngularFire documentation pretty strictly, still, getting this error message about my service can't resolve Firestore. Re-installing the whole node_modules and re-compiling the app with both dev and production flags did not help. Any other idea how to solve this issue?
Solved by removing all the "old" non-modular usage of Firestore, leaving only the version 9+ parts.

Jest Test - The current environment does not support the specified persistence type

I use jest to run some test on my Create React App with Firebase Web SDK coupled with FirebaseUI
Whenever I try to run some tests with --env=jsdom - I run into :
The current environment does not support the specified persistence type. seems related to Auth
Are there any known related issue/workaround ? the code seems to work/compile properly aside from the tests.
Google didn't help much
Here is the test, pretty basic.
HAd to add import "firebase/storage"; because of this : firebase.storage() is not a function in jest test cases
Thanks in advance
import React from "react";
import Enzyme from "enzyme";
import Adapter from "enzyme-adapter-react-16";
import "firebase/storage";
import {filterIngredientsToRemove} from "./shoppingList-reducer";
Enzyme.configure({adapter: new Adapter()});
describe("", () => {
let shoppingList;
let recipeId;
beforeEach(() => {
shoppingList = {
shoppingListItems: {
"1234": {ingredientId: 987, name: "patate", recipeId: 1234},
"2345": {ingredientId: 987, name: "patate", recipeId: 5432}
},
shoppingListRecipes: {
"1234": {portion: 3}
}
};
recipeId = 1234;
});
it("should filter out the shoppinglistItems with the provided recipeId", () => {
const result = filterIngredientsToRemove(recipeId, shoppingList.shoppingListItems);
expect(result).toEqual([{ingredientId: 987, name: "patate", recipeId: 1234}]);
});
});
Are you setting persistence in your firebase config? Persistence is not supported in the test environment, so you can do something like this to circumvent it:
firebase.auth().setPersistence(process.env.NODE_ENV === 'test'
? firebase.auth.Auth.Persistence.NONE
: firebase.auth.Auth.Persistence.LOCAL);
I ran into this issue too. The problem seems to come from the firebaseui constructor, specifically this line of code in my app:
new firebaseui.auth.AuthUI(this.firebase.auth())
What I did to solve it was initialize the ui object only when actually using it to sign on, not just as a static (typescript) variable. This let me run jest tests that didn't try to sign on just fine.
private static ui: firebaseui.auth.AuthUI | undefined
static startAuthOnElement (selectorToUse: string, onSignedIn: () => void) {
if (this.ui === undefined) this.ui = new firebaseui.auth.AuthUI(this.firebase.auth())
// more code
}
This way all the code that doesn't call startAuthOnElement never runs the firebaseui constructor. This lets me run my jest tests just fine and auth still works in the app.

AngularFireDatabase Does not retrieve data

Whenever I use afDB.list('/path') method, I get the following:
console.log(this.items);
and I have this example as my firebase database: listings file
surprisingly, editing the data works perfectly fine (e.g. remove(), push(),... etc.), but I can't seem to be able to retrieve it; however, I can access it. I thought it might be a rules issue, yet, my rules are fine: firebase Rules
this is the portion of the code that I'm having trouble with:
import { Component } from '#angular/core';
import { NavController } from 'ionic-angular';
import { AngularFireAuth } from 'angularfire2/auth';
import { FirebaseProvider } from '../../providers/firebase/firebase';
import { AngularFireDatabase } from 'angularfire2/database';
import { Observable } from 'rxjs/Observable';
import * as firebase from 'firebase/app';
//import { ListingDetailsPage } from '../listing-details/listing-details';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
items: Observable<any[]>;
constructor(
public navCtrl: NavController,
public afAuth: AngularFireAuth,
public firebaseProvider: FirebaseProvider,
public afDB: AngularFireDatabase
) {
this.items = afDB.list('/listings', ref => ref.orderByChild('age').equalTo('large')).valueChanges();
}
login(){
this.afAuth.auth.signInWithPopup(new firebase.auth.GoogleAuthProvider()).then(res => console.log(res));
}
logout() {
this.afAuth.auth.signOut();
}
list(){
console.log(this.items);
}
}
I also tried to use AngularFireList instead of Observable, but it doesn't change the issue. I also used afDB.object() instead of afDB.list(), I still get the same problem. Query is not the issue either, as I tried to use a simple .list()/.object() and again the same issue. additionally, I created a database using the same code (.set()), and I couldn't retrieve it either.
Relevant Specs:
"angularfire2": "^5.0.0-rc.11",
"firebase": "^5.2.0",
"promise-polyfill": "^8.0.0",
"ionic-angular": "3.9.2",
"#angular/compiler-cli": "5.2.11",
"#angular/core": "5.2.11",
OS: Windows10
platforms tested: Google Chrome Browser/ Firefox Browser/ Android SDK emulator
You've defined your items variable as an observable (and that is correct) but if you want to play with the data returned from that observable, you need to subscribe to that observable.
constructor(
public navCtrl: NavController,
public afAuth: AngularFireAuth,
public firebaseProvider: FirebaseProvider,
public afDB: AngularFireDatabase
) {
this.items = afDB.list('/listings', ref => ref.orderByChild('age').equalTo('large')).valueChanges();
this.items.subscribe( valueOfItems => {
console.log(valueOfItems);
})
}
There is a compatibility issue in Angularfire2 with rxjs. So, until Angularfire2 provide support for rxjs6, you can resolve this error by installing rxjs-compat package using below command.
npm install rxjs#6 rxjs-compat#6 --save
you can find more information in the rxjs migration guide.
https://github.com/ReactiveX/rxjs/blob/master/docs_app/content/guide/v6/migration.md
there is also a "template driven" way to retrieve data.
Template :
// example 1
<ul>
<li *ngFor="let dino of dinosaurs$ | async">
<p>{{vdino.name }}</p>
</li>
</ul>
// example 2
<ul>
<li *ngFor="let dino of dinosaursArray">
<p>{{vdino.name }}</p>
</li>
</ul>
Controller :
constructor(private afDb: AngularFireDatabase) {
const itemsRef: AngularFireList<any> = afDb.list('dinosaurs');
// example 1
this.dinosaurs$ = itemsRef.valueChanges();
// example 2
this.dinosaurs$.subscribe(array => this.dinosaursArray = array);
}
Here a stackblitz with the two examples (credits to #markgoho) :
https://stackblitz.com/edit/angular-trrnhg
The deps are a bit outdated but it still should work for you.
Moreover, #JeremyW answer should work, can you be more specific on the error ?
EDIT : " error: TypeError: Object(...) is not a function"
If you face this error, this is likely a compatibility problem with rxjs 5, you may try with rxjs 6.
check this post :
Angular2 fire listen to node changes throws an error

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.

Insert provider for SQLiteObject ionic 3

I'm working on a project on ionic 3 angular 4. I have to connect to a database and do other things...
So I have a page (.ts .html .scss .module.ts), a provider where I use sql. So my problem is this, I have this error :
core.es5.js:1084
ERROR Error: Uncaught (in promise): Error: No provider for SQLiteObject!
Error: No provider for SQLiteObject!
So in module.ts I added in provider flag i put SQLiteObject. But now I get this new error :
compiler.es5.js:1540 Uncaught Error: Can't resolve all parameters for SQLiteObject: (?).
Also if I put SQLite it wants always the SQLiteObject provider.Anyway I never use SQLite just SQLiteObject
import { SQLiteObject } from '#ionic-native/sqlite';
I google and I found that SQLiteObject is not a provider but just an interface.
So? Any idea? I can put code but is long, if you have some idea please comment.
You need to add its class in providers in your app.module.ts file as:
import { SQLiteObject } from '#ionic-native/sqlite';
#NgModule({
declarations: [
MyApp
],
imports: [
//
],
bootstrap: [IonicApp],
entryComponents: [
MyApp
],
providers: [{provide: ErrorHandler, useClass: IonicErrorHandler}, SQLiteObject]
})
export class AppModule {}
You're right SQLiteObject isn't a Provider but you're trying to import it as one. It is a class Object used by the SQLite Provider so you can save the object from your constructor and then use it as this.db from there. FYI: remove the import { SQLiteObject } statement.
private db: SQLiteObject;
constructor(private sqlite: SQLite)
{
this.sqlite.create({
name: 'data.db',
location: 'default'
})
.then((db: SQLiteObject) => {
this.db = db; //set the object to your own var
db.executeSql("CREATE TABLE IF NOT EXISTS ...", {});
});
}

Resources