i have an error to signin with google: please anyone help me: i struck in this :woozy_face: when i click a signin button in ionic app project console shows me this type error:
{error: ‘idpiframe_initialization_failed’, details: ‘You have created a new client application that use…i/web/guides/gis-migration) for more information.’}
my ionic/angular code is:
home.page.html:
Google Sign In
Sign In
<ion-button expand=“full” (click)=“signOut()” *ngIf=“user”>Sign Out
<ion-item *ngIf=“user”>
<img [src]="user.imageUrl" />
{{user.givenName}} {{user.familyName}}
{{user.email}}
home.page.ts:
import { Component } from ‘#angular/core’;
import { GoogleAuth } from ‘#codetrix-studio/capacitor-google-auth’;
import { isPlatform } from ‘#ionic/angular’;
#Component({
selector: ‘app-home’,
templateUrl: ‘home.page.html’,
styleUrls: [‘home.page.scss’],
})
export class HomePage {
user = null;
constructor() {
if (!isPlatform('capacitor')) {
GoogleAuth.initialize();
}
}
async signIn() {
this.user = await GoogleAuth.signIn();
console.log('user:', this.user);
}
async signaOut() {
await GoogleAuth.signOut();
this.user = null;
}
}
index.html:(i have drefined two meta tags like):
in capacitor.config.json file:
{
“appId”: “io.ionic.starter”,
“appName”: “form”,
“webDir”: “www”,
“bundledWebRuntime”: false,
“plugins”: {
"GoogleAuth": {
"scopes": ["profile", "email"],
"serverCliendId": "458018620622-26eoi0kd5fjodcs4l6ihdnddpg0osg4f.apps.googleusercontent.com",
"forceCodeRefreshTokken": true
}
}
}
please help me this out…
Related
I have a version deployed in the Ionic dashboard, and every time that I'm working on a new version and the device is connected to the Internet, it's replacing my version with the version that is deployed there. How can I work on a new version?
You can check if your device is connected to internet or not, using this network plugin provided by ionicframework.
let disconnectSubscription = this.network.onDisconnect().subscribe(() => { console.log('network was disconnected :-(');});
This metod will automatically catch if user disconnected their network and
let connectSubscription = this.network.onConnect().subscribe(() => {console.log('network connected!');});
using this method you can catch if user is connected to network.
So using those method you can show/hide some content for offline and online use.
I have created network service to catch Online and Offline status :
import { Injectable } from '#angular/core';
import { Network } from '#ionic-native/network/ngx'
import { BehaviorSubject, Observable } from 'rxjs';
import { ToastController, Platform } from '#ionic/angular';
export enum ConnectionStatus {
Online,
Offline
}
#Injectable({
providedIn: 'root'
})
export class NetworkService {
private status: BehaviorSubject<ConnectionStatus> = new BehaviorSubject(ConnectionStatus.Offline);
constructor(private network: Network, private toastController: ToastController, private plt: Platform) {
this.plt.ready().then(() => {
this.initializeNetworkEvents();
let status = this.network.type !== 'none' ? ConnectionStatus.Online : ConnectionStatus.Offline;
this.status.next(status);
});
}
public initializeNetworkEvents() {
this.network.onDisconnect().subscribe(() => {
if (this.status.getValue() === ConnectionStatus.Online) {
this.updateNetworkStatus(ConnectionStatus.Offline);
}
});
this.network.onConnect().subscribe(() => {
if (this.status.getValue() === ConnectionStatus.Offline) {
this.updateNetworkStatus(ConnectionStatus.Online);
}
});
}
private async updateNetworkStatus(status: ConnectionStatus) {
this.status.next(status);
let connection = status == ConnectionStatus.Offline ? 'Offline' : 'Online';
let toast = this.toastController.create({
message: `You are now ${connection}`,
duration: 3000,
position: 'bottom'
});
toast.then(toast => toast.present());
}
public onNetworkChange(): Observable<ConnectionStatus> {
return this.status.asObservable();
}
public getCurrentNetworkStatus(): ConnectionStatus {
return this.status.getValue();
}
}
And you can you this service in your component, for example:
import { Component, OnInit } from '#angular/core';
import { NetworkService, ConnectionStatus } from 'src/services/network.service';
#Component({
selector: 'app-dashboard',
templateUrl: './dashboard.page.html',
styleUrls: ['./dashboard.page.scss'],
})
export class DashboardPage implements OnInit {
isOnline:boolean;
constructor(private network: NetworkService){}
ngOnInit() {
let status = this.network.getCurrentNetworkStatus();
(status == ConnectionStatus.Offline)? this.isOnline = false: this.isOnline = true;
console.log("Network status is ", this.isOnline);
}
}
<ion-header>
</ion-header>
<ion-content>
<ion-row *ngIf="isOnline">
For online
</ion-row>
<ion-row *ngIf="!isOnline">
For Offline
</ion-row>
</ion-content>
I am building an ionic app using AWS as a backend (has been challenging!), and for some reason on my user sign-in page, I got this nasty bug that wasn't there when I was using firebase as the backend. In a nutshell, my side menu has items that should appear based on whether the user is logged in or not. If the user is logged in, the menu should have a logout item. If the user is not logged in, the menu should either not have any options, or a redundant sign-in option.
I got the hard part down, which was setting up AWS Cognito to work the sign-in logic, and setting the correct root page, however, after a user logs in, the menu does not show the logout option.
Funny thing, if I reload the app, the menu does show the logout option. Not sure why. Also weird, after I reload the app and I click the logout button, the correct options for a user that is not logged in do appear in the menu. If someone can take a look and tell me why the menu options only render correctly when I log out and if I log in only after I reload the app, I would be very grateful! Thank you in advance for your time! Code below...
app.component.ts:
import { Component } from '#angular/core';
import { Platform, NavController, MenuController } from 'ionic-angular';
import { StatusBar } from '#ionic-native/status-bar';
import { SplashScreen } from '#ionic-native/splash-screen';
import { TabsPage } from '../pages/tabs/tabs';
import { SignInPage } from '../pages/sign-in/sign-in';
import { AuthService } from '../services/auth';
#Component({
templateUrl: 'app.html'
})
export class MyApp {
rootPage: any;
isLoggedIn //this variable holds the status of the user and determines the menu items;
constructor(platform: Platform,
statusBar: StatusBar,
splashScreen: SplashScreen,
private menuCtrl: MenuController,
private authService: AuthService) {
this.verifyUserstate(); //method to check if a user is logged in
console.log(this.isLoggedIn); //debug line
console.log(this.menuCtrl.get()); //debug line
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();
splashScreen.hide();
});
}
onLoad(page: any) {
console.log("onLoad");
this.nav.setRoot(page);
this.menuCtrl.close();
}
onLogout() {
this.authService.logout();
this.verifyUserstate();
this.menuCtrl.close();
}
verifyUserstate() {
console.log("in verify userstate");
this.authService.isAuthenticated()
.then(() => {
this.isLoggedIn = true; //if a user is logged in = true
this.rootPage = TabsPage;
console.log(this.isLoggedIn); // more debug
})
.catch((error) => {
this.isLoggedIn = false; //if user is not logged in = false
this.rootPage = SignInPage;
console.log(this.isLoggedIn); //more debug
});
}
}
app.html:
<ion-menu [content]="nav">
<ion-header>
<ion-toolbar>
<ion-title>Menu</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-list>
<button ion-item icon-left (click)="onLoad(signinPage)" *ngIf="!isLoggedIn"> <!-- check isLoggin-->
<ion-icon name="log-in"></ion-icon>
Sign In
</button>
<button ion-item icon-left (click)="onLogout()" *ngIf="isLoggedIn">
<ion-icon name="log-out"></ion-icon>
Log Out
</button>
</ion-list>
</ion-content>
auth.ts:
import { Injectable } from "#angular/core";
import { AlertController } from "ionic-angular";
import { CognitoUserPool, AuthenticationDetails, CognitoUser, CognitoUserSession } from "amazon-cognito-identity-js";
const POOL_DATA = {
UserPoolId: "xx-xxxx-X_XXXX",
ClientId: "You do not need to know :)"
}
const userPool = new CognitoUserPool(POOL_DATA);
export class AuthService {
signin(email: string, password: string) {
let message: string;
var authenticationData = {
Username : email,
Password : password,
};
var authDetails = new AuthenticationDetails(authenticationData);
let userData = {
Username: email,
Pool: userPool
}
let cognitoUser = new CognitoUser(userData);
return new Promise((resolve, reject) => {
cognitoUser.authenticateUser(authDetails, {
onSuccess(result: CognitoUserSession) {
console.log(result)
resolve("Success!")
},
onFailure(error) {
let message: string = error.message;
reject(message);
}
}
logout() {
this.getAuthenticatedUser().signOut();
}
isAuthenticated() {
return new Promise((resolve, reject) => {
let user = this.getAuthenticatedUser();
if (user) {
user.getSession((err, session) => {
if(session.isValid()) {
resolve(true);
} else if (err) {
reject(err.message);
}
})
} else {
reject("Not authenticated");
}
});
}
}
Finally, the sign-in.ts file (where the magic of login in happens):
import { Component } from '#angular/core';
import { NgForm } from '#angular/forms';
import { LoadingController, AlertController } from 'ionic-angular';
import { AuthService } from '../../services/auth';
import { NavController } from 'ionic-angular/navigation/nav-controller';
import { MyApp } from '../../app/app.component';
#Component({
selector: 'page-sign-in',
templateUrl: 'sign-in.html',
})
export class SignInPage {
constructor(private authService: AuthService,
private loadingCtrl: LoadingController,
private alertCtrl: AlertController,
private navCtrl: NavController) {
}
onSignin(form: NgForm) {
const loading = this.loadingCtrl.create({
content: "Signing you in..."
});
loading.present();
this.authService.signin(form.value.email, form.value.password)
.then(data => {
this.navCtrl.setRoot(MyApp); /*navigate to myApp again to reverify the
*login status. This sets the right rootPage,
*but I have a feeling here also lies the menu problem.
*/
console.log(data);
})
.catch(error => {
console.log(error);
let alert = this.alertCtrl.create({
title: "Oops",
message: error,
buttons: ["Ok"]
});
alert.present();
})
loading.dismiss();
}
}
I've been working on the facebook login for my ionic 2 app
(used this tutorial: https://ionicthemes.com/tutorials/about/ionic2-facebook-login)
But now i get a weird error:
RunTimeError Error in :0:0 caused by: No provider for NavController
app.component.ts:
import { Component } from '#angular/core';
import { Platform } from 'ionic-angular';
import { StatusBar } from '#ionic-native/status-bar';
import { SplashScreen } from '#ionic-native/splash-screen';
import { NativeStorage } from '#ionic-native/native-storage';
import { TabsPage } from '../pages/tabs/tabs';
import { WelcomePage } from '../pages/welcome/welcome';
import { DetailPage } from '../pages/detail/detail';
#Component({
templateUrl: 'app.html'
})
export class MyApp {
rootPage: any = WelcomePage;
constructor(NativeStorage: NativeStorage, platform: Platform, statusBar: StatusBar, splashScreen: SplashScreen) {
platform.ready().then(() => {
// Here we will check if the user is already logged in
// because we don't want to ask users to log in each time they open the app
let env = this;
NativeStorage.getItem('user')
.then((data) => {
// user is previously logged and we have his data
// we will let him access the app
this.rootPage = DetailPage;
splashScreen.hide();
}, (error) => {
//we don't have the user data so we will ask him to log in
this.rootPage = WelcomePage;
splashScreen.hide();
});
statusBar.styleDefault();
});
}
}
welcome.ts:
import { Component } from '#angular/core';
import { Facebook, NativeStorage } from 'ionic-native';
import { NavController } from 'ionic-angular';
import { DetailPage } from '../detail/detail';
import { ViewChild } from '#angular/core';
#Component({
selector: 'page-welcome',
templateUrl: 'welcome.html'
})
export class WelcomePage {
rootPage: any = WelcomePage;
#ViewChild('navRoot') navCtrl: NavController;
FB_APP_ID: number = 123456789;
constructor() {
Facebook.browserInit(this.FB_APP_ID, "v2.8");
}
doFbLogin() {
let permissions = new Array();
let nav = this.navCtrl;
//the permissions your facebook app needs from the user
permissions = ["public_profile"];
Facebook.login(permissions)
.then(function (response) {
let userId = response.authResponse.userID;
let params = new Array();
//Getting name and gender properties
Facebook.api("/me?fields=name,gender", params)
.then(function (user) {
user.picture = "https://graph.facebook.com/" + userId + "/picture?type=large";
//now we have the users info, let's save it in the NativeStorage
NativeStorage.setItem('user',
{
name: user.name,
gender: user.gender,
picture: user.picture
})
.then(function () {
nav.push(DetailPage);
}, function (error) {
console.log(error);
})
})
}, function (error) {
console.log(error);
});
}
}
You cannot import NavController in app.component.ts or the root app page.
OPTION 1:
Try to get it using ViewChild
Give element id to root-nav
<ion-nav #navRoot [root]="rootPage"></ion-nav>
In component:
import {ViewChild} from '#angular/core';
#Component({
templateUrl: 'app.html'
})
export class MyApp {
rootPage: any = WelcomePage;
#ViewChild('navRoot') navCtrl:NavController;
constructor(nativeStorage: NativeStorage, platform: Platform, statusBar: StatusBar, splashScreen: SplashScreen) { //remove navcontroller injected
platform.ready().then(() => {
// Here we will check if the user is already logged in
// because we don't want to ask users to log in each time they open the app
let env = this;
//...
OPTION 2:
From your app.component.ts code, you dont actually need to import NavController at all if your html template only contains,
<ion-nav [root]="rootPage"></ion-nav>
Simply set the required page to rootPage.
nativeStorage.getItem('user')
.then( (data) => {
// user is previously logged and we have his data
// we will let him access the app
this.rootPage = DetailPage;
splashScreen.hide();
}, (error) => {
//we don't have the user data so we will ask him to log in
this.rootPage = WelcomePage;
splashScreen.hide();
});
Side Note: Better to use ()=>{} arrow functions for callbacks instead of saving context in second variable.
Original Post:
I am coding an Ionic 2 Hybrid app and attempting to create a modal that logs into FB and gathers necessary information for the app to run properly.
While the modal is presented (and the user is logging in), I need the app to be paused in the background. In other words, it cannot be continuing with the subsequent processes until the modal is dismissed.
Here is the relevant portion of code as an example:
var user = firebase.auth().currentUser;
if (user) {
console.log("User is already signed in.");
} else {
console.log("No user is signed in.");
let profileModal = this.modalCtrl.create(ProfilePage);
profileModal.present();
}
console.log("test pause.")
While the modal is still being presented and before it is dismissed, "test pause." is being written to the console. I need it to NOT be written to the console until AFTER the modal is dismissed.
NOTE: I have everything working properly except this bit. I haven't figured out how to accomplish 'pausing' until the modal is dismissed.
Is there any way to do this?
Clarification:
I am presenting the modal in the ngOnInit() of the main app component. I am doing this because I need specific user information to be gathered before the main app component is loaded and any pages are set/added to the stack.
Otherwise, the rootpage will not be built properly.
Here is the updated code in its full context in the app.component.ts file:
import { Component, ViewChild, OnInit } from '#angular/core';
import { ModalController, Nav, Platform } from 'ionic-angular';
import { SettingsService } from './../services/settings';
import { StatusBar } from '#ionic-native/status-bar';
import { SplashScreen } from '#ionic-native/splash-screen';
import { HomePage } from './../pages/home/home';
import { SignInPage } from './../pages/signin/signin';
import { CreatePage } from './../pages/create/create';
import { ProfilePage } from './../modals/profile/profile';
import firebase from 'firebase';
#Component({
templateUrl: 'app.html'
})
export class MyApp implements OnInit {
#ViewChild(Nav) nav: Nav;
rootPage: any = HomePage;
homePage: any = HomePage;
signInPage: any = SignInPage;
createPage: any = CreatePage;
photoURL: string;
constructor(private modalCtrl: ModalController,
private platform: Platform,
private statusBar: StatusBar,
private splashScreen: SplashScreen,
private settingsService: SettingsService) {
this.initializeApp();
}
ngOnInit() {
var config = {
apiKey: "AIzaSyDmTh_LZuMPnn7nJRquoW5xWwgQ4Ia3J9E",
authDomain: "thevault-ba308.firebaseapp.com",
databaseURL: "https://thevault-ba308.firebaseio.com",
projectId: "thevault-ba308",
storageBucket: "thevault-ba308.appspot.com",
messagingSenderId: "1024205108979"
};
firebase.initializeApp(config);
var user = firebase.auth().currentUser;
if (user) {
console.log("User is already signed in.");
}
else {
console.log("No user is signed in.");
let profileModal = this.modalCtrl.create(ProfilePage);
profileModal.present();
profileModal.onDidDismiss(() => {
console.log("test pause.")
this.photoURL = this.settingsService.getUserPhoto();
console.log(this.settingsService.getUserName());
})
}
}
initializeApp() {
this.platform.ready().then(() => {
this.statusBar.styleDefault();
this.splashScreen.hide();
});
}
openPage(page) {
this.nav.setRoot(page);
}
signOut() {
firebase.auth().signOut().then((result) => {
console.log("Sign out success.");
this.nav.setRoot(SignInPage);
}).catch((error) => {
console.log(error.message);
});
}
}
You should move all the code that was supposed to execute after modal is dismissed in this modal.onDismiss() part. Like this:
let profileModal = this.modalCtrl.create(ProfilePage);
profileModal.present();
profileModal.onDismiss((data) => {
console.log("Data from modalPage :",data);
console.log("test pause."); // Here you go. The code will be paused till the modal is dismissed.
});
Moreover, you can pass data to the modalPage via navParams and retrieve from the modalPage as well using this.viewCtrl.dismiss(data);.
For more reference, look at this and this ionic 2 documentation.
I was able to resolve my problem by using *ngIf in the app.html file.
<ion-content *ngIf="photoURL != null">
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