SignInWithApple is not defined in IONIC Project - firebase

Scenario:
I am trying to add identification via Apple and Firebase for my IONIC 4 application.
So I made my installation:
npm i cordova-plugin-apple-login
ionic cordova plugin add cordova-plugin-apple-login
Then I added in my service :
import {AngularFireAuth} from '#angular/fire/auth';
import {Facebook} from '#ionic-native/facebook/ngx';
import * as firebase from 'firebase';
import {GooglePlus} from '#ionic-native/google-plus/ngx';
declare var SignInWithApple: any;
export class AuthService {
constructor(public fAuth: AngularFireAuth,
public fb: Facebook,
public google: GooglePlus) {}
async loginApple() {
SignInWithApple.request({requestedScopes: [ SignInWithApple.Scope.Email, SignInWithApple.Scope.FullName ]})
.then((appleCredential) => {
const credential = new firebase.auth.OAuthProvider('apple.com').credential(appleCredential.identityToken);
this.fAuth.auth.signInWithCredential(credential)
.then((response) => {
console.log('Login successful');
})
.catch((error) => {
console.log(error);
alert('error:' + JSON.stringify(error));
});
});
}
}
Problem:
This is the method I find everywhere on the internet, but it gives me the error:
SignInWithApple is not defined
I also tried this :
Scenario:
ionic cordova plugin add cordova-plugin-sign-in-with-apple
npm i --save #ionic-native/sign-in-with-apple
import {AngularFireAuth} from '#angular/fire/auth';
import {Facebook} from '#ionic-native/facebook/ngx';
import * as firebase from 'firebase';
import {GooglePlus} from '#ionic-native/google-plus/ngx';
import { SignInWithApple,
AppleSignInResponse,
AppleSignInErrorResponse,
ASAuthorizationAppleIDRequest } from '#ionic-native/sign-in-with-apple';
export class AuthService {
constructor(public fAuth: AngularFireAuth,
public fb: Facebook,
public google: GooglePlus) {}
async loginApple() {
try {
const appleCredential: AppleSignInResponse = await SignInWithApple.signin({
requestedScopes: [
ASAuthorizationAppleIDRequest.ASAuthorizationScopeFullName,
ASAuthorizationAppleIDRequest.ASAuthorizationScopeEmail
]
});
const credential = new firebase.auth.OAuthProvider('apple.com').credential(
appleCredential.identityToken
);
this.fAuth.auth.signInWithCredential(credential)
.then((res) => {
console.log('Login successful', res);
})
.catch((error) => {
console.log(error);
});
} catch (error) {
console.log(error);
}
}
}
Problem:
Class not found
I don't find much explanation on the documentation ...
In both I have an error that I do not understand, what is the method to keep and how to correct it ?
An idea ?
Thank you

Related

ionic 4 + firebaseX stopped receiving push (android and ios)

My app has stopped from receiving push notifications.
I don't know what else I can do to check it.
It was working a few months ago
Stopped working for both iOS and Android
Installed and checked app permissions many times
Firebase is initializing, getting token and registering in my database fine
Tried test messages on Firebase console with generated token and it didn't work as well
Here is my notification.service.ts code:
import { Injectable } from '#angular/core';
import { Platform, Events } from '#ionic/angular';
import { HttpClient } from '#angular/common/http';
import { Storage } from '#ionic/storage';
import { BehaviorSubject } from 'rxjs';
import { tap } from 'rxjs/operators';
import { FirebaseX } from "#ionic-native/firebase-x/ngx";
import { environment } from '../../environments/environment';
import { AppService } from './app.service';
import { AuthService } from './auth.service';
#Injectable({
providedIn: 'root'
})
export class NotificationService {
fcm_token:any = null;
constructor(
private platform: Platform,
private http:HttpClient,
private appService:AppService,
private firebase: FirebaseX,
public events: Events,
public authService:AuthService,
) { }
async initialize(){
console.log('notificationService.initialize()');
let self = this;
let platforms = this.platform.platforms();
if(platforms.includes('ios') || platforms.includes('android')){
this.firebase.getToken().then(token => {
if(platforms.includes('ios')){ this.firebase.grantPermission(); }
if(platforms.includes('android')){ }
self.saveToken(token);
}).catch(error => console.error('FIREBASE Error getting token', error));
this.firebase.onTokenRefresh().subscribe((token: string) => { self.saveToken(token); });
this.firebase.onMessageReceived().subscribe(data => { });
}else{
// using browser, do nothing
}
}
async saveToken(token){
console.log('notificationService.saveToken()', token);
if(this.authService.is_logged == true){
this.fcm_token = token;
return this.http.post(environment.api_url+'/user/save-fcm-token', {fcm_token:this.fcm_token}, {headers:{'Authorization':'Bearer '+this.authService.auth_token}}).toPromise();
}
}
}
What else can I try?
Is there some place when I can see sending/receiving push errors?

AngularFireModule has not been provided using v7.0.1 and new method of initializing the firebase app

I'm attempting to connect to the firebase emulator within an integration test, using the new AngularFire API (>v7)
import {
TestBed
} from '#angular/core/testing';
import {
initializeApp,
provideFirebaseApp
} from '#angular/fire/app';
import {
doc,
enableIndexedDbPersistence,
Firestore,
getFirestore,
provideFirestore,
setDoc
} from '#angular/fire/firestore';
import {
connectFirestoreEmulator
} from "firebase/firestore";
describe('FirestoreEmulatorSmoketest', () => {
let projectId: string;
let firestore: Firestore;
beforeAll(() => {
const testConfig = {
projectId,
auth: ...
};
TestBed.configureTestingModule({
imports: [
provideFirebaseApp(() => initializeApp(testConfig)),
provideFirestore(() => {
const firestore = getFirestore();
connectFirestoreEmulator(firestore, 'localhost', 8080);
enableIndexedDbPersistence(firestore);
return firestore;
}),
],
})
});
beforeEach(() => {})
afterAll(() => {})
it('should connect', () => {
const fooDoc = doc(firestore, "foo/12345");
return setDoc(fooDoc, {
updated: new Date()
})
})
});
This code produces the following error "AngularFireModule has not been provided"
I can only assume I'm not initialising angular fire somehow?
First of all, my native language is not English, so if I write like a fool you know why.
Try this.
environment.ts
export const environment = {
production: false,
useEmulators: true,
firebaseConfig: {
apiKey: 'YOUR-API-KEY',
authDomain: 'YOUR-AUTH-DOMAIN',
projectId: 'YOUR-PROJECT-ID',
storageBucket: 'YPUR-STORAGE-BUCKET',
messagingSenderId: 'YOUR-MESSAGING-SENDER-ID',
appId: 'YOUR-APP-ID',
measurementId: 'YOUR-MEASUREMENT-ID',
},
};
Important: As you can see I have the variable useEmulators, which in the following lines I will explain what it is going to be used for.
app.module.ts
import { provideFirebaseApp, initializeApp } from '#angular/fire/app';
import { getAuth, provideAuth, connectAuthEmulator } from '#angular/fire/auth';
import { getFirestore, provideFirestore, connectFirestoreEmulator, enableIndexedDbPersistence } from '#angular/fire/firestore';
import { getStorage, provideStorage, connectStorageEmulator } from '#angular/fire/storage';
import { getAnalytics, provideAnalytics } from '#angular/fire/analytics';
import { getFunctions, provideFunctions, connectFunctionsEmulator} from '#angular/fire/functions';
import { environment } from 'environments/environment'; // <--- Environment variables.
imports: [
// Firebase
provideFirebaseApp(() => initializeApp(environment.firebaseConfig)),
provideFirestore(() => {
if (environment.useEmulators) {
const firestore = getFirestore();
connectFirestoreEmulator(firestore, 'localhost', 8080);
enableIndexedDbPersistence(firestore);
return firestore;
} else {
getFirestore();
}
}),
provideAuth(() => {
if (environment.useEmulators) {
const fireauth = getAuth();
connectAuthEmulator(fireauth, 'http://localhost:9099'); // <---FireAuth Port
return fireauth;
} else {
getAuth();
}
}),
provideStorage(() => {
if (environment.useEmulators) {
const firestorage = getStorage();
connectStorageEmulator(firestorage, 'localhost', 9199); // <---- Firestorage Port
return firestorage;
} else {
getStorage();
}
}),
provideFunctions(() => {
if (environment.useEmulators) {
const firefunctions = getFunctions();
connectFunctionsEmulator(firefunctions, 'localhost', 5001); // <--- FireFunctions Port
return firefunctions;
} else {
getFunctions();
}
}),
provideAnalytics(() => getAnalytics()),
],
Important (Environment Path): Change the environment path of the variables in case you don't have them in the default location.
Important (Local Ports): In case you use different local ports than the default ones, change them.
As you can see I have added code to the initializations to be able to switch between the emulated project and the online project, in a simple way:
useEmulators: true // We load the emulator environment
useEmulators: false // We load the production environment
_fireAuth.service.ts
import { Auth } from '#angular/fire/auth';
constructor(private _fireAuth: Auth) {}
_fireStorage.service.ts
import { Storage } from '#angular/fire/storage';
constructor(private _fireStorage: Storage) {}
_fireStore.service.ts
import { Firestore } from '#angular/fire/firestore';
constructor(private _fireStore: Firestore) {}
It only remains to import the functions you are going to use, e.g. { doc, Collection, etc... }.
Use the documentation provided by Google to see how they changed the functions: https://firebase.google.com/docs/build
and use the code found in the "Web version 9 (modular)" tab.

Vue + Pinia + Firebase Authentication: Fetch currentUser before Route Guard

Recently I started to use Pinia as a global store for my Vue 3 Project. I use Firebase for the user authentication and am trying to load the current user before Vue is initialized. Ideally everything auth related should be in a single file with a Pinia Store. Unfortunately (unlike Vuex) the Pinia instance needs to be passed to the Vue instance before I can use any action and I believe that is the problem. On first load the user object in the store is empty for a short moment.
This is the store action that is binding the user (using the new Firebase Web v9 Beta) in auth.js
import { defineStore } from "pinia";
import { firebaseApp } from "#/services/firebase";
import {
getAuth,
onAuthStateChanged,
getIdTokenResult,
} from "firebase/auth";
const auth = getAuth(firebaseApp);
export const useAuth = defineStore({
id: "auth",
state() {
return {
user: {},
token: {},
};
},
actions: {
bindUser() {
return new Promise((resolve, reject) => {
onAuthStateChanged(
auth,
async (user) => {
this.user = user;
if (user) this.token = await getIdTokenResult(user);
resolve();
},
reject()
);
});
},
// ...
}})
and this is my main.js file
import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";
import { createPinia } from "pinia";
import { useAuth } from "#/store/auth";
(async () => {
const app = createApp(App).use(router).use(createPinia());
const auth = useAuth();
auth.bindUser();
app.mount("#app");
})();
How can I set the user before anything else happens?
I figured it out. Had to register the router after the async stuff
//main.js
(async () => {
const app = createApp(App);
app.use(createPinia());
const { bindUser } = useAuth();
await bindUser();
app.use(router);
app.mount("#app");
})();

firebase.auth.GoogleAuthProvider is not a constructor

I'm trying to use google sign using firebase in the Vue framework. I don't know what the error is this can anyone help me with this.
vue.runtime.esm.js?2b0e:1888 TypeError: _firebase_js__WEBPACK_IMPORTED_MODULE_2__.fb.auth.GoogleAuthProvider is not a constructor
at VueComponent.socialLogin (Signin.vue?3d55:76)
at invokeWithErrorHandling (vue.runtime.esm.js?2b0e:1854)
at HTMLButtonElement.invoker (vue.runtime.esm.js?2b0e:2179)
at HTMLButtonElement.original._wrapper (vue.runtime.esm.js?2b0e:6917)
this is my code
firebase.js
import firebase from "firebase";
var firebaseConfig = {
config
};
const fb=firebase.initializeApp(firebaseConfig);
export { fb };
Sign in.vue
<script>
import { fb } from "../firebase.js";
export default {
name: "Signin",
components: {},
data() {
return {
};
},
methods: {
socialLogin() {
const provider = new fb.auth.GoogleAuthProvider();
fb.auth().signInWithPopup(provider).then((result) => {
this.$router.replace('home');
}).catch((err) => {
alert('Oops. ' + err.message)
});
}
}
};
</script>
The auth property (not the auth() function) is available on the static firebase object, not your firebase app.
You want something more like this
import firebase from "firebase/app"
import "firebase/auth" // 👈 this could also be in your `firebase.js` file
const provider = new firebase.auth.GoogleAuthProvider()

firebase and gatsby build don't work well together

I get the following error when I try to login:
u.a.auth is not a function
The error is on this line in Login.js:
app.auth().setPersistence(firebase.auth.Auth.Persistence.NONE);
At the top, I have import app from "./base.js";
In base.js, I have
import firebase from 'firebase/app';
var config = {
....
};
var app;
if(firebase.apps && firebase.apps.length > 0) {
app = firebase.apps[0];
} else {
app = firebase.initializeApp(config);
}
export default app;
That's after I run
gatsby build
gatsby serve
Hello here's how I did it. It worked fine:
import React from "react";
import firebase from "firebase";
...
const LoginForm = () => {
const login = values => {
firebase
.auth()
.signInWithEmailAndPassword(values.email, values.password)
.then(() => { firebase.auth().setPersistence(firebase.auth.Auth.Persistence.SESSION);
navigate("/app/profile");
})
.catch(error => {
console.log("do something with the error:", error);
});
}
return(
<form onSubmit={login}>
form details
</form>
);
};
export default LoginForm;

Resources