Expected 1 arguments when using storage in ionic - ionic-framework

I tried using local storage in my ionic service provider app but I got this error.
[ts] Expected 1 arguments, but got 0. (alias) new Storage(config:
StorageConfig): Storage import Storage Create a new Storage instance
using the order of drivers and any additional config options to pass
to LocalForage.
Possible driver options are: ['sqlite', 'indexeddb', 'websql',
'localstorage'] and the default is that exact ordering.
Here is my source code:
import { Storage } from '#ionic/storage';
#Injectable()
export class MyServiceProvider {
public local : Storage;
mydata: any;
constructor(public http: Http) {
this.local = new Storage()
}
postLogin(data){
let link = "http://myapi.com/api/login.php";
return this.http.post(link, data)
.map(data => {
this.mydata = data;
console.log("data")
}, error =>{
console.log(error)
})
}
}

I didn't understand well what you want to do with the Storage, but according to Ionic Storage docs, you need to inject into your provider/component.
import { Storage } from '#ionic/storage';
export class MyApp {
constructor(private storage: Storage) { }
}
I suggest you to use that provider do get and set the data and you can call these methods wherever you import your provider.
public setData(nameData: string, valueData: any){
this.storage.set(nameData, valueData);
}
public getDataValue(nameData: string){
return this.storage.get(nameData);
}

Related

Opening Mongoose connection in AdonisJS provider times out

I was following this article to use Mongo in AdonisJS 5 project.
I have an AdonisJS provider which I have created by node ace make:provider Mongo (it is registered in .adonisrc.json):
import { ApplicationContract } from '#ioc:Adonis/Core/Application'
import { Mongoose } from 'mongoose'
export default class MongoProvider {
constructor(protected app: ApplicationContract) {}
public async register() {
// Register your own bindings
const mongoose = new Mongoose()
// Connect the instance to DB
await mongoose.connect('mongodb://docker_mongo:27017/mydb')
// Attach it to IOC container as singleton
this.app.container.singleton('Mongoose', () => mongoose)
}
public async boot() {
// All bindings are ready, feel free to use them
}
public async ready() {
// App is ready
}
public async shutdown() {
// Cleanup, since app is going down
// Going to take the Mongoose singleton from container
// and call disconnect() on it
// which tells Mongoose to gracefully disconnect from MongoBD server
await this.app.container.use('Mongoose').disconnect()
}
}
My model is:
import { Schema, model } from '#ioc:Mongoose'
// Document interface
interface User {
email: string
}
// Schema
export default model(
'User',
new Schema<User>({
email: String,
})
)
Controller:
import { HttpContextContract } from '#ioc:Adonis/Core/HttpContext'
import User from 'App/Models/User'
export default class UsersController {
public async index({}: HttpContextContract) {
// Create a cat with random name
const cat = new User({
email: Math.random().toString(36).substring(7),
})
// Save cat to DB
await cat.save()
// Return list of all saved cats
const cats = await User.find()
// Return all the cats (including the new one)
return cats
}
}
And it is timeouting.
It is working, when I open the connection in controller like this though:
import { HttpContextContract } from '#ioc:Adonis/Core/HttpContext'
import User from 'App/Models/User'
import mongoose from 'mongoose'
export default class UsersController {
public async index({}: HttpContextContract) {
await mongoose.connect('mongodb://docker_mongo:27017/mydb')
// Create a cat with random name
const cat = new User({
email: Math.random().toString(36).substring(7),
})
// Save cat to DB
await cat.save()
// Return list of all saved cats
const cats = await User.find()
// Close the connection
await mongoose.connection.close()
// Return all the cats (including the new one)
return cats
}
}
I have just created an AdonisJS provider, registered it in .adonisrc.json, created a contracts/Mongoose.ts with typings, and use the model in controller.
Any idea? I'm stuck for a day with this.
Thanks
I managed to resolve this issue by not storing mongoose in a variable. It seems the mongoose variable you declare in your MongoProvider is the root of your timeout error.
So I did as follow :
export default class MongoProvider {
constructor(protected app: ApplicationContract) {}
public async register() {
await mongoose.connect('mongodb://localhost:27017/dbName')
this.app.container.singleton('Mongoose', () => mongoose)
}
public async boot() {
// All bindings are ready, feel free to use them
}
public async ready() {
// App is ready
}
public async shutdown() {
await this.app.container.use('Mongoose').disconnect()
}
}
If someone would be interested:
with the help of the article author the reason why it is not working was missing Mongoose when creating the model (Mongoose.model instead of just model:
export default Mongoose.model(
'User',
new Schema<User>({
email: String,
})
)
I followed this article too, and I have the same issue you discussed. but resolved this by importing mongoose in my model a little differently.
import mongoose in the model like this import Mongoose, { Schema } from '#ioc:Mongoose' instead of import { Schema, model } from '#ioc:Mongoose'
Example:
import Mongoose, { Schema } from '#ioc:Mongoose'
// Document interface
interface User {
email: string
}
// Schema
export default model(
'User',
new Schema<User>({
email: String,
})
)

Can we use queryParams in ionic4?

We have used queryParams for angular projects. can we use queryParams in ionic project?
is there any side effect or security issues?
this.router.navigate(['your-page-name-here'], params);
You can use queryParams but it is not a recommended way because you are sending values as a part of router link. This also means that you are limited to strings only and objects need to be stringified (JSON.stringify()) and parsed each time you send data.
Better option is to use Extras State:
let navigationExtras: NavigationExtras = {
state: {
userData: this.user
}
};
this.router.navigate(['my-page'], navigationExtras);
In MyPage, get data from the State by injecting Router in constructor:
this.data = this.router.getCurrentNavigation().extras.state.userData;
Using Service: Also, you can create a service that has a getter and setter that you can use to save data in it before navigating and retrieve it after completing the navigation:
import { Injectable } from '#angular/core';
#Injectable({
providedIn: 'root'
})
export class DataService {
private data = [];
constructor() { }
setData(id, data) {
this.data[id] = data;
}
getData(id) {
return this.data[id];
}
}

What is the proper way to do seed mongoDB in NestJS, using mongoose and taking advantage of my already defined schmas

We are using NestJS with mongoose and want to seed mongoDB.
Wondering what is the proper way to seed the database, and use the db schemas already defined to ensure the data seeded is valid and properly maintained.
Seeding at the module level (just before the definition of the Module) feels hacky and ends in threadpool being destroyed, and therefore all following mongo operations fail
I've done using the nestjs-command library like that.
1. Install the library:
https://www.npmjs.com/package/nestjs-command
2. Then I've created a command to seed my userService like:
src/modules/user/seeds/user.seed.ts
import { Command, Positional } from 'nestjs-command';
import { Injectable } from '#nestjs/common';
import { UserService } from '../../../shared/services/user.service';
#Injectable()
export class UserSeed {
constructor(
private readonly userService: UserService,
) { }
#Command({ command: 'create:user', describe: 'create a user', autoExit: true })
async create() {
const user = await this.userService.create({
firstName: 'First name',
lastName: 'Last name',
mobile: 999999999,
email: 'test#test.com',
password: 'foo_b#r',
});
console.log(user);
}
}
3. Add that seed command into your module. I've created a SeedsModule in a shared folder to add more seeds in future
src/shared/seeds.module.ts
import { Module } from '#nestjs/common';
import { CommandModule } from 'nestjs-command';
import { UserSeed } from '../modules/user/seeds/user.seed';
import { SharedModule } from './shared.module';
#Module({
imports: [CommandModule, SharedModule],
providers: [UserSeed],
exports: [UserSeed],
})
export class SeedsModule {}
Btw I'm importing my userService into my SharedModule
4. Add the SeedsModule into your AppModule
On your AppModule usually at src/app.module.ts add the SeedsModule into imports
Final
If you followed the steps in the nestjs-command repo you should be able to run
npx nestjs-command create:user
That will bootstrap a new application and run that command and then seed to your mongo/mongoose
Hope that help others too.
actually you can do it easily with onModuleInit(), here i'm using Mongoose ORM. This all done with zero dependencies, hope it helps
import { Injectable, OnModuleInit } from '#nestjs/common';
import { UserRepository } from './repositories/user.repository';
#Injectable()
export class UserService implements OnModuleInit {
constructor(private readonly userRepository: UserRepository) {}
// onModuleInit() is executed before the app bootstraped
async onModuleInit() {
try {
const res = await this.userRepository.findAll(); // this method returns user data exist in database (if any)
// checks if any user data exist
if (res['data'] == 0) {
const newUser = {
name: 'yourname',
email: 'youremail#gmail.com',
username: 'yourusername',
};
const user = await this.userRepository.create(newUser); // this method creates new user in database
console.log(user);
}
} catch (error) {
throw error;
}
}
// your other methods
}
For my case, I needed to insert seed during the tests, the best I could find is to create a seed service, imported and used only during tests.
Here is my base class using the schema model, all is needed is to extend and pass the model.
// # base.seed.service.ts
import { Model, Document } from 'mongoose';
import { forceArray, toJson } from 'src/utils/code';
export abstract class BaseSeedService<D extends Document> {
constructor(protected entityModel: Model<D>) {}
async insert<T = any>(data: T | T[]): Promise<any[]> {
const docs = await this.entityModel.insertMany(forceArray(data));
return toJson(docs);
}
}
// # utils
const toJson = (arg: any) => JSON.parse(JSON.stringify(arg));
function forceArray<T = any>(instance: T | T[]): T[] {
if (instance instanceof Array) return instance;
return [instance];
}
// # dummy.seed.service.ts
import { Injectable } from '#nestjs/common';
import { InjectModel } from '#nestjs/mongoose';
import { Model } from 'mongoose';
import { DummyDocument } from './dummy.schema';
#Injectable()
export class DummySeedService extends BaseSeedService<DummyDocument> {
constructor(
#InjectModel(Dummy.name)
protected model: Model<DummyDocument>,
) {
super(model);
}
}
Then inside the tests
describe('Dymmy Seeds', () => {
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [DummySeedService],
imports: [
MongooseModule.forRoot(__connect_to_your_mongodb_test_db__),
MongooseModule.forFeature([
{
name: Dummy.name,
schema: DummySchema,
},
]),
],
}).compile();
const seeder = module.get<DummySeedService>(DummySeedService);
const initData = [__seed_data_here__];
const entities: Dummy[] = await seeder.insert(initData);
expect(entities.length > 0).toBeTruthy();
});
});

Best way to connect ionic 2 nativ facebook with firebase

at the moment iam implementing a signIn into my ionic 2 app.
I want to use ionic 2 native facebook and somehow save the data to my firebase app.
Is there any way to archive that?
One way is to create a new firebase auth user with the facebook email adress and some password hash, but maybe there is a better solution.
Here is what i got so far (i know, not much) :)
import {NavController, Loading, Platform, Storage, LocalStorage} from "ionic-angular";
import {OnInit, Inject, Component} from "#angular/core";
import {ForgotPasswordPage} from "../forgot-password/forgot-password";
import {SignUpPage} from "../sign-up/sign-up";
import {HomePage} from "../../home/home";
import * as firebase from 'firebase';
import {Facebook} from 'ionic-native';
/*
Generated class for the LoginPage page.
See http://ionicframework.com/docs/v2/components/#navigation for more info on
Ionic pages and navigation.
*/
#Component({
templateUrl: 'build/pages/auth/login/login.html',
})
export class LoginPage {
private local: any;
constructor(private navCtrl: NavController, private platform:Platform) {
this.local = new Storage(LocalStorage);
}
openForgotPasswordPage():void {
this.navCtrl.push(ForgotPasswordPage);
}
openSignUpPage():void {
this.navCtrl.push(SignUpPage);
}
login() {
firebase.auth().signInWithEmailAndPassword("test#test.com", "correcthorsebatterystaple").then(function (result) {
console.log("AUTH OK "+ result);
}, function (error) {
console.log("dawdaw");
});
}
facebookLogin() {
Facebook.login(['public_profile', 'user_birthday']).then(() => {
this.local.set('logged', true);
this.navCtrl.setRoot(HomePage);
}, (...args) => {
console.log(args);
})
} }
facebookLogin() {
Facebook.login(['public_profile', 'user_birthday']).then((result) => {
var creds = firebase.auth.FacebookAuthProvider.credential(result.access_token);
return firebase.auth().signInWithCredential(creds);
})
.then((_user) => {
console.log("_user:", _user);
})
.catch((_error) => {
console.error("Error:", _error);
});
}
see more info here - https://firebase.google.com/docs/auth/web/facebook-login#advanced-handle-the-sign-in-flow-manually
I have not tried this, so might not be 100% working, but try this Gist I found: https://gist.github.com/katowulf/de9ef6b04552091864fb807092764224

Firebase returns AUTHENTICATION_DISABLED [duplicate]

I am creating a simple sample auth app with Ionic 2 and angularfire 2 as backend, when i try to create new user it says:
EXCEPTION: Error: Uncaught (in promise): Error: The specified
authentication provider is not enabled for this Firebase.
But i already enabled firebase authentication in firebase console:
app.ts
import {App, Platform} from 'ionic-angular';
import {StatusBar} from 'ionic-native';
import {HomePage} from './pages/home/home';
import { FIREBASE_PROVIDERS, defaultFirebase, firebaseAuthConfig, AuthProviders, AuthMethods } from 'angularfire2';
#App({
template: '<ion-nav [root]="rootPage"></ion-nav>',
providers: [
FIREBASE_PROVIDERS,
defaultFirebase('https://samplequizapp-50eb5.firebaseio.com'),
firebaseAuthConfig({
provider: AuthProviders.Password,
method: AuthMethods.Password
})
],
config: {} // http://ionicframework.com/docs/v2/api/config/Config/
})
export class MyApp {
rootPage: any = HomePage;
constructor(platform: Platform) {
platform.ready().then(() => {
// Okay, so the platform is ready and our plugins are available.
// Here you can do any higher level native things you might need.
StatusBar.styleDefault();
});
}
}
home.ts
import { Page } from 'ionic-angular';
import { AngularFire, FirebaseListObservable } from 'angularfire2';
import { OnInit } from '#angular/core'
#Page({
templateUrl: 'build/pages/home/home.html'
})
export class HomePage implements OnInit {
user: any = {};
data: FirebaseListObservable<any[]>;
constructor(private af: AngularFire) {
}
ngOnInit() {
this.data = this.af.database.list('/userId')
}
signUp(data) {
this.af.auth.createUser({
email: data.email,
password: data.password
})
}
}
I am pretty sure there is nothing wrong with my code:
Firebase2 in its current version (2.4.2) is not yet compatible with Firebase SDK v3, and all projects created with the new Firebase console are only accessible with calls comaptible with SDK v3.
You want to create your Firebase backend in the legacy console www.firebase.com first, and then migrate to the new console.
This is documented in this closed issue of the angularfire2 github: https://github.com/angular/angularfire2/issues/189