Firebase Authentication on Ionic 2 - firebase

I am trying to implement login with firebase on Ionic 2 with the following code.
export class MyApp {
rootPage:any = Login;
isAuthenticated = false;
constructor(platform: Platform, statusBar: StatusBar, splashScreen: SplashScreen) {
firebase.initializeApp({
apiKey: "AIzaSyC94rD8wXG0aRLTcG29qVGw8CFfvCK7XVQ",
authDomain: "myfirstfirebaseproject-6da6c.firebaseapp.com",
});
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
this.rootPage = Home;
} else {
this.rootPage = Login;
}
});
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();
});
}
}
I realize that even when I am authenticated, I am always brought to the Login screen because it does not wait for onAuthStateChanged promise to be fulfilled and carries on with initializing the app, therefore, the Login screen instead of the Home screen is always shown.
But how should I change my code so that I can show Home when authenticated?

Remove the login from the rootPage declaration
export class MyApp {
rootPage:any;
...
}
You're setting the page to your LoginPage as the app initializes and before he can check if the user is loged.
For it to run the onAuthStateChange, when the app initializes you need to use Zone to create an observable and the run it.
import { NgZone } from '#angular/core';
zone: NgZone; // declare the zone
this.zone = new NgZone({});
const unsubscribe = firebase.auth().onAuthStateChanged((user) => {
this.zone.run(() => {
if (user) {
this.rootPage = Home;
unsubscribe();
} else {
this.rootPage = Login;
unsubscribe();
}
});
});
Hope it helps

Related

Protected Route With Firebase and Svelte

I'm trying to create a protected page, the profile page of my project. I want to throw people out if they are not logged in. I'm trying to do it as simply as possible. I find this tutorial, but is TypeScript and I couldn't get it to work. Link >
My way:
Profile page:
let auth = getAuth();
onMount(() => {
auth.onAuthStateChanged((user) => {
if (!user) {
goto('/signin');
}
});
});
The idea is to have a user store and use it with the combination of onAuthStateChanged
import authStore from '../stores/authStore';; // <~ stores.ts
import { onMount } from 'svelte';
let auth = getAuth();
onMount(() => {
//shift this method to a firebase.ts
auth.onAuthStateChanged((user) => {
if (user) {
authStore.set({
user,
});
} else {
authStore.set({
user: null,
});
}
});
});
// this block will watch changes on the store
$: {
if (!$authStore.user) {
if (browser) goto('/login');
} else {
if (browser) goto('/');
}
}

check required auth in vue beforeEach method with firebase v9

i want to check if user exist before go to some pages in beforeEach method
i export the user state i use firebase v9
export const userAuthState = ()=>{
let currentUser = null;
onAuthStateChanged(auth, (user) => {
if (user) {
currentUser = user;
}
});
return currentUser;
}
here where i use it
import {userAuthState} from 'src/backend/firebase-config';
...
console.log("before route");
Router.beforeEach(async (to,from,next)=>{
if(await !userAuthState() && to.meta.requiresAuth){
next({path: 'login', query:{ redirect: to.fullPath }})
}else if(await userAuthState() && to.meta.requiresAuth == 'login'){
next({path:'/'})
}else{
next()
}
})
here the problem cant navigate to any page and print the console.log many times
how i can check the user before route in correct way
thank you.
I'll give you a simple example of how can you make some decision based on user authentication.
For this, I'll use Vuex as a central store since you'll commonly use user information across all your app. I'll assume that you're building an SPA with Vue and Firebase V9.
This is a simple store for users. Register this store with Vue (with .use()) in your main.js file (your entry point file).
import { createStore } from 'vuex'
const Store = createStore({
state() {
return {
user: {
uid: '',
email: ''
}
}
},
mutations: {
setUser (state, payload) {
if (payload) {
state.user.uid = payload.uid
state.user.email = payload.email
return
}
state.user.uid = ''
state.user.email = ''
}
}
})
export Store
Now, at your App.vue (or your root component) you simple call onAuthStateChanged and run commits depending on User's state:
<template>
<div>Your wonderful template...</div>
</template>
<script>
import { onAuthStateChanged } from "firebase/auth";
import { yourAuthService } from 'yourFirebaseInit'
export default {
name: 'App',
created () {
onAuthStateChanged(yourAuthService, (user) => {
if (user) {
this.$store.commit('setUser', { uid: user.uid, email: user.email })
} else {
this.$store.commit('setUser', null)
}
})
}
}
</script>
Finally, in your routes, you could do something like:
// we import the Store that we've created above.
import { Store } from 'your-store-path'
Router.beforeEach((to,from,next)=>{
if(to.meta.requiresAuth && Store.state.user.uid === ''){
next({path: 'login', query:{ redirect: to.fullPath }})
} else{
next()
}
})
This is a simple example of how can you implement an Authentication flow with Vue and Firebase V9.

Phoneauthprovider is not a function firebase react-native

Hi everybody im making a app using react-native and fire base im have this initial config at firebase config :
import firebase from 'firebase/app';
import 'firebase/auth';
import Constants from 'expo-constants';
// Firebase Config
// Initialize Firebase
export const firebaseConfig = {
apiKey: Constants?.manifest?.extra?.apiKey,
authDomain: Constants?.manifest?.extra?.authDomain,
projectId: Constants?.manifest?.extra?.projectId,
storageBucket: Constants?.manifest?.extra?.storageBucket,
messagingSenderId: Constants?.manifest?.extra?.messagingSenderId,
appId: Constants?.manifest?.extra?.appId
};
let Firebase
if (firebase.apps.length === 0) {
console.log('hello world')
Firebase = firebase.initializeApp(firebaseConfig);
}
export default Firebase;
And im triyng to call this method:
const loginUser = async() => {
switch(loginType){
case 0:
break;
case 1:
if (typeof(verificationId) == 'string') {
setLoading(true)
try {
const credential = new Firebase.auth.PhoneAuthProvider.credential(
verificationId,
verificationCode
);
await Firebase.auth.signInWithCredential(credential);
showMessage({ text: 'Phone authentication successful 👍' });
} catch (err) {
setLoading(false)
showMessage({ text: `Error: ${err.message}`, color: 'red' });
}
} else {
try {
const phoneProvider = Firebase.auth.PhoneAuthProvider();
const verificationId = await phoneProvider.verifyPhoneNumber(
phoneNumber,
recaptchaVerifier.current
);
setVerificationId(verificationId);
showMessage({
text: 'Verification code has been sent to your phone.',
});
} catch (err) {
showMessage({ text: `Error: ${err.message}`, color: 'red' });
}
}
break;
}
}
When im try to call my 'phone Login method' react-native show me this message:
im use this guide for how to configure the enviroment:
https://blog.jscrambler.com/how-to-integrate-firebase-authentication-with-an-expo-app
but using phone verification with recaptcha im not found the problem i believe the problem its in my implementation but in not found nothing
Thanks for the answers
I see you're trying to implement phone auth using firebase and I personally had success doing that using this:
async function signInWithPhoneNumber(phoneNumber) {
//1. Have the user input thei phone number into a TextInput and pass it to this function
//2. Have a confirm useState to make sure the verification code was sent successfully by firebase
//3. Check for the confirm state in the main component and show the user another TextInput to enter the verification code if confirm has a value
await firebase.auth()
.signInWithPhoneNumber(phoneNumber)
.then(confirmation => {
setConfirm(confirmation)
})
.catch(e => {
Alert.alert('Error sending verification code to this phone number')
})
}
async function confirmCode(code) {
//1. Have the code the user entered through the TextInput pass through here and call the below function
try {
let validation = await confirm?.confirm(code)
if (validation) console.log('correct code.')
} catch (error) {
Alert.alert('Invalid code.')
}
}
You're importing your own Firebase object, which is an instance of FirebaseApp. The PhoneAuthProvider class is not defined on FirebaseApp, but rather is in the (static) firebase.auth namespace.
So you either need to also import the regular Firebase Auth SDK into your code, instead of just your own Firebase object, or you can attach the firebase.authnamespace to yourFirebase` object and use it from there with:
...
if (firebase.apps.length === 0) {
console.log('hello world')
Firebase = firebase.initializeApp(firebaseConfig);
Firebase.auth = firebase.auth;
}
export default Firebase;

iOS 14.5 App Tracking Transparency for firebase logs in react-native app

Firebase logs stopped working as soon as updated to iOS 14.5 for one of the react-native app I am working on.
What are the necessary changes that we need to do to make it working again?
You need to request Tracking permissions first (I used react-native-permissions):
import { request, RESULTS, PERMISSIONS } from 'react-native-permissions'
import { Settings } from 'react-native-fbsdk-next'
export const requestPermissionTransparency = async () => {
return await request(PERMISSIONS.IOS.APP_TRACKING_TRANSPARENCY)
}
useEffect(() => {
;(async () => {
const result = await requestPermissionTransparency()
if (result === RESULTS.GRANTED) {
await firebase.analytics().setAnalyticsCollectionEnabled(true)
await Settings.setAdvertiserTrackingEnabled(true)
} else {
await firebase.analytics().setAnalyticsCollectionEnabled(false)
await Settings.setAdvertiserTrackingEnabled(false)
}
})()
}, [])
Remember to add this file in the root project:
// <project-root>/firebase.json
{
"react-native": {
"analytics_auto_collection_enabled": false
}
}
References: https://rnfirebase.io/analytics/usage

in React-Native, How to send notification when users install app but don't login or sign-up?

I'm writing a project in React-Native for both iOS and Android, I want to send notification automatically when users just install app but don't login or sign-up after 3 days. I'm using firebase cloud data for the project. Is it possible to do that over coding or firebase?
Using Firebase, you can get the FCM token for the device even without them being logged in. You will needs to get their permission to receive notifications though.
import React, { Component } from "react";
import { Text, View } from "react-native";
import firebase from "react-native-firebase";
export default class componentName extends Component {
async componentDidMount() {
this.checkPermission();
}
//1
async checkPermission() {
firebase
.messaging()
.hasPermission()
.then((enabled) => {
if (enabled) {
this.getToken();
} else {
this.requestPermission();
}
});
}
//2
async requestPermission() {
firebase
.messaging()
.requestPermission()
.then(() => {
this.getToken();
})
.catch((error) => {});
}
//3
async getToken() {
fcmToken = await firebase.messaging().getToken();
if (fcmToken) {
//
//
//
//
//
// Call your API here
//
//
//
//
//
//
}
}
render() {
return (
<View>
<Text> Your APP </Text>
</View>
);
}
}

Resources