Firebase Authentication для приложения Ionic 3 - не может вызвать выражение, тип которого не имеет подписи вызова - PullRequest
0 голосов
/ 16 апреля 2019

Я пытаюсь использовать Firebase Authentication в моем приложении Ionic 3.

Я следовал полезному руководству на https://medium.com/appseed-io/integrating-firebase-password-and-google-authentication-into-your-ionic-3-app-2421cee32db9, и, похоже, это работает.

При первом открытии приложения я вижу то, что кажется случайной ошибкой:

Невозможно вызвать выражение, тип которого не имеет подписи вызова.Тип '((onfulfilled ?: (value: void) => TResult1 | PromiseLike

Это относится к src/pages/login/login.ts в строке 52. Я вставлю login.ts полностью ниже, но проблемная строка - this.auth.signInWithGoogle()

error message

import { Component } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { NavController } from 'ionic-angular';

import { HomePage } from '../home/home';
import { AuthService } from '../../services/auth.service';
import { SignupPage } from '../signup/signup';

@IonicPage()
@Component({
  selector: 'page-login',
  templateUrl: 'login.html',
})
export class LoginPage {
    loginForm: FormGroup;
    loginError: string;

    constructor(
        private navCtrl: NavController,
        private auth: AuthService,
        fb: FormBuilder
    ) {
        this.loginForm = fb.group({
            email: ['', Validators.compose([Validators.required, Validators.email])],
            password: ['', Validators.compose([Validators.required, Validators.minLength(6)])]
        });
    }

    login() {
        let data = this.loginForm.value;

        if (!data.email) {
            return;
        }

        let credentials = {
            email: data.email,
            password: data.password
        };
        this.auth.signInWithEmail(credentials)
            .then(
                () => this.navCtrl.setRoot(HomePage),
                error => this.loginError = error.message
            );
    }   

    signup(){
      this.navCtrl.push(SignupPage);
    }   

    loginWithGoogle() {
      this.auth.signInWithGoogle()
        .then(
          () => this.navCtrl.setRoot(HomePage),
          error => console.log(error.message)
        );
    }       

}

Если это поможет, вот мой auth.service.ts файл:

import { Injectable } from '@angular/core';
import { AngularFireAuth } from 'angularfire2/auth';
import * as firebase from 'firebase/app';
import 'firebase/database';
import AuthProvider = firebase.auth.AuthProvider;

@Injectable()
export class AuthService {
    private user: firebase.User;

    constructor(public afAuth: AngularFireAuth) {
        afAuth.authState.subscribe(user => {
            this.user = user;
        });
    }

    signInWithEmail(credentials) {
        console.log('Sign in with email');
        return this.afAuth.auth.signInWithEmailAndPassword(credentials.email,
             credentials.password);
    }

    signUp(credentials) {
        return this.afAuth.auth.createUserWithEmailAndPassword(credentials.email, credentials.password);
    }

    get authenticated(): boolean {
      return this.user !== null;
    }   

    getEmail() {
      return this.user && this.user.email;
    }   

    getUid() {
      return this.user && this.user.uid;
    }   

    signOut(): Promise<void> {
      return this.afAuth.auth.signOut();
    }   

    signInWithGoogle() {
            console.log('Sign in with google');
            return this.oauthSignIn(new firebase.auth.GoogleAuthProvider());
    }

    private oauthSignIn(provider: AuthProvider) {
        if (!(<any>window).cordova) {
            return this.afAuth.auth.signInWithPopup(provider);
        } else {
            return this.afAuth.auth.signInWithRedirect(provider)
            .then(() => {
                return this.afAuth.auth.getRedirectResult().then( result => {
                    // This gives you a Google Access Token.
                    // You can use it to access the Google API.
                    let token = result.credential.accessToken;
                    // The signed-in user info.
                    let user = result.user;
                    console.log(token, user);
                }).catch(function(error) {
                    // Handle Errors here.
                    alert(error.message);
                });
            });
        }
    }   

}

Вотмой package.json файл

{
  "name": "MyApp",
  "version": "0.0.1",
  "author": "Ionic Framework",
  "homepage": "http://ionicframework.com/",
  "private": true,
  "scripts": {
    "start": "ionic-app-scripts serve",
    "clean": "ionic-app-scripts clean",
    "build": "ionic-app-scripts build",
    "lint": "ionic-app-scripts lint"
  },
  "dependencies": {
    "@angular/animations": "5.2.11",
    "@angular/common": "5.2.11",
    "@angular/compiler": "5.2.11",
    "@angular/compiler-cli": "5.2.11",
    "@angular/core": "5.2.11",
    "@angular/forms": "5.2.11",
    "@angular/http": "5.2.11",
    "@angular/platform-browser": "5.2.11",
    "@angular/platform-browser-dynamic": "5.2.11",
    "@ionic-native/core": "~4.18.0",
    "@ionic-native/splash-screen": "~4.18.0",
    "@ionic-native/status-bar": "~4.18.0",
    "@ionic/pro": "2.0.4",
    "@ionic/storage": "2.2.0",
    "@ultimate/ngxerrors": "^1.4.0",
    "angularfire2": "^5.1.2",
    "cordova-ios": "5.0.0",
    "firebase": "^5.9.4",
    "ionic-angular": "3.9.3",
    "ionicons": "3.0.0",
    "rxjs": "5.5.11",
    "sw-toolbox": "3.6.0",
    "zone.js": "0.8.29"
  },
  "devDependencies": {
    "@ionic/app-scripts": "3.2.1",
    "cordova-plugin-device": "^2.0.2",
    "cordova-plugin-ionic-keyboard": "^2.1.3",
    "cordova-plugin-ionic-webview": "^3.1.2",
    "cordova-plugin-splashscreen": "^5.0.2",
    "cordova-plugin-statusbar": "^2.4.2",
    "cordova-plugin-whitelist": "^1.3.3",
    "typescript": "~2.6.2"
  },
  "description": "An Ionic project",
  "cordova": {
    "plugins": {
      "cordova-plugin-whitelist": {},
      "cordova-plugin-statusbar": {},
      "cordova-plugin-device": {},
      "cordova-plugin-splashscreen": {},
      "cordova-plugin-ionic-webview": {},
      "cordova-plugin-ionic-keyboard": {}
    },
    "platforms": [
      "ios"
    ]
  }
}

Ответы [ 2 ]

0 голосов
/ 28 апреля 2019

Проблема в том, что ваша функция возвращает Promise<I don't Know> | void. Так как вы возвращаете разные типы обещаний из вашего then, вы получаете

Невозможно вызвать выражение, тип которого не имеет подписи вызова.

ошибка.

setRoot(pageOrViewCtrl, params, opts, done) => возвращает обещание

console.log(error.message) => возвращает void

loginWithGoogle() {
      this.auth.signInWithGoogle()
        .then(
          () => this.navCtrl.setRoot(HomePage), // here you return a promise
          error => console.log(error.message) // here you return a void 
        );
    } 

Решением вашей проблемы являются фигурные скобки. ;)

Если вы опустите скобки, функция стрелки будет иметь краткое тело, которое состоит исключительно из одного выражения, результат которого неявно станет возвращаемым значением функции.

this.auth.signInWithGoogle() .then( () => {this.navCtrl.setRoot(HomePage)}, error => { console.log(error.message)} );

надеюсь, это сработает. вот несколько ссылок.

  1. вопрос подписи звонка

  2. фигурные скобки-в-стрелка-функции

надеюсь, это поможет.

0 голосов
/ 27 апреля 2019

Я обновил свой ответ на основе вашего обновленного вопроса и комментария.

На основе вашего package.json вы пытаетесь создать гибридное мобильное приложение (т. Е. Оно использует Cordova /PhoneGap), который нацелен на iOS с использованием Ionic 3.

Посмотрите на Ionic v3 GitHub repo , похоже, что последняя версия v3 - "3.9.5".И последний из Ionic App Scripts - "3.2.2".

Ionic v3 работает с Angular "5.0.3" и TypeScript "> = 2.4.2 <2.5".Версия в вашем <code>package.json -> «typcript»: «~ 2.6.2» слишком новая для Ionic 3.

Вам также необходимо выбрать версию angularfire2, которая будет работать с Ionic v3 и Angular "5.0.3" .Например: "angularfire2": "5.0.0-rc.6".

Чтобы исправить ошибку TypeScript, попробуйте добавить типы для каждого из методов AuthService, параметров каждого метода и не забудьте добавить возврата также.

Например:

    public signInWithEmail(credentials: Credentials) Promise<any> {

        return this.afAuth.auth.signInWithEmailAndPassword(credentials.email,
             credentials.password);
    }

Я построил PWA , используя Ionic 3, Angular 5 и angularfire2 (который использует Firestore, Firebase Storage и FirebaseАвт).И это не легко получить зависимости просто правильно:)

My package.json:

{
  "name": "Brew",
  "description": "Brew: The Craft Beer App",
  "version": "1.0.0-beta.2",
  "author": "Rob Ferguson",
  "homepage": "https://craftbeer.org.au",
  "private": true,
  "scripts": {
    "clean": "ionic-app-scripts clean",
    "lint": "ionic-app-scripts lint",
    "dev": "ionic-app-scripts serve",
    "ios:dev": "ionic-app-scripts serve --platform=ios",
    "build": "ionic-app-scripts build && npm run ngsw-config && npm run ngsw-copy",
    "ios:build": "ionic-app-scripts build --platform=ios && npm run ngsw-config && npm run ngsw-copy",
    "test": "ng test --config ./config/karma.conf.js",
    "test-ci": "ng test --config ./config/karma.conf.js --watch=false --code-coverage",
    "test-coverage": "ng test --config ./config/karma.conf.js --code-coverage",
    "e2e": "npm run e2e-update && npm run e2e-test",
    "e2e-test": "protractor ./config/protractor.conf.js",
    "e2e-update": "webdriver-manager update --standalone false --gecko false",
    "ionic:build": "ionic-app-scripts build && npm run ngsw-config && npm run ngsw-copy",
    "ionic:serve": "ionic-app-scripts serve",
    "ng": "ng",
    "ngsw-config": "node_modules/.bin/ngsw-config www src/ngsw-config.json",
    "ngsw-copy": "cp node_modules/@angular/service-worker/ngsw-worker.js www/",
    "version-update": "node ./update-build-version.js"
  },
  "dependencies": {
    "@angular/animations": "5.2.10",
    "@angular/common": "5.2.10",
    "@angular/compiler": "5.0.3",
    "@angular/core": "5.2.10",
    "@angular/forms": "5.0.3",
    "@angular/http": "5.0.3",
    "@angular/platform-browser": "5.0.3",
    "@angular/platform-browser-dynamic": "5.0.3",
    "@angular/service-worker": "5.2.10",
    "@firebase/app": "0.1.10",
    "@ngx-pwa/local-storage": "5.3.0",
    "@ngx-translate/core": "9.1.1",
    "@ngx-translate/http-loader": "2.0.1",
    "angularfire2": "5.0.0-rc.6",
    "firebase": "4.13.1",
    "fix-orientation": "0.0.2",
    "ionic-angular": "3.9.2",
    "ngx-pipes": "^2.3.5",
    "promise-polyfill": "7.1.2",
    "raven-js": "^3.27.0",
    "rxjs": "5.5.4",
    "sw-toolbox": "3.6.0",
    "zone.js": "0.8.18"
  },
  "devDependencies": {
    "@angular/cli": "1.7.4",
    "@angular/compiler-cli": "5.0.3",
    "@angular/language-service": "5.0.3",
    "@ionic-angular/schematics": "^1.1.4",
    "@ionic/app-scripts": "^3.2.0",
    "@types/googlemaps": "^3.30.7",
    "@types/jasmine": "~2.8.3",
    "@types/jasminewd2": "~2.0.2",
    "@types/node": "~6.0.60",
    "codelyzer": "^4.0.1",
    "firebase-admin": "^5.12.0",
    "jasmine-core": "~2.8.0",
    "jasmine-spec-reporter": "~4.2.1",
    "karma": "~2.0.0",
    "karma-chrome-launcher": "~2.2.0",
    "karma-coverage-istanbul-reporter": "^1.2.1",
    "karma-jasmine": "~1.1.0",
    "karma-jasmine-html-reporter": "^0.2.2",
    "protractor": "~5.1.2",
    "purify-css": "^1.2.5",
    "replace-in-file": "^3.4.2",
    "ts-node": "~4.1.0",
    "tslint": "~5.9.1",
    "typescript": ">=2.4.2 <2.5"
  },
  "config": {
    "ionic_copy": "./config/copy.config.js",
    "ionic_sass": "./config/sass.config.js",
    "ionic_webpack": "./config/webpack.config.js"
  }
}

...