I am making an angularJS application, and I plan to use Firebase for simple authentication.
My index.html file includes
<script src="https://cdn.firebase.com/js/simple-login/1.6.2/firebase-simple-login.js"></script>
<script src="scripts/login.js"></script>
My login.js looks like this at the moment:
$(document).ready(function(){
var myRef = new Firebase("https://my_app.firebaseio.com");
var auth = new FirebaseSimpleLogin(myRef, function(error, user) {
if (error) {
// an error occurred while attempting login
console.log(error);
} else if (user) {
// user authenticated with Firebase
console.log("User ID: " + user.uid + ", Provider: " + user.provider);
} else {
// user is logged out
}
});
var authRef = new Firebase("https://my_app.firebaseio.com/.info/authenticated");
authRef.on("value", function(snap) {
if (snap.val() === true) {
alert("authenticated");
} else {
alert("not authenticated");
}
});
auth.login('password', {
email: 'user#host.com',
password: 'password',
});
console.log(auth);
});
All I really want to do with this is test whether I can log in, and what the auth object will look like after a login.
Later, I will integrate the login into a ng-model to pass the data that way rather than just passing it hard coded.
The problem right now is that this code doesn't even run, I get an error back from the javascript console:
Uncaught ReferenceError: Firebase is not defined
Why is this happening?
It seems you haven't included the firebase.js script.
Only the firebase-simple-login.js isn't enough, it require firebase.js.
<script src="https://cdn.firebase.com/js/client/1.0.17/firebase.js"></script>
<script src="https://cdn.firebase.com/js/simple-login/1.6.2/firebase-simple-login.js"></script>
<script src="scripts/login.js"></script>
Related
I'm trying to add MFA inside my web app following the guide https://cloud.google.com/identity-platform/docs/web/mfa.
I started with enrolling the phone number successfully with the account and now when I want to "login" again using that phone number but I can’t use the number to get a code.
Check the code:
//I have imported my firebase services inside services/firebase.js
import { auth, signInWithEmailAndPassword, PhoneMultiFactorGenerator } from '#/services/firebase';
methods: {
//On login button click - this method is called
login: async function (event) {
var self = this;
await signInWithEmailAndPassword(auth, self.user_email, self.user_password)
.then(()=> {
...
//I am setting the user here, and giving access based on the role of the user
}
.catch((error) => {
console.log('Error:', error);
//Gives: Error: FirebaseError: Firebase: Error (auth/multi-factor-auth-required).
if (error.code == 'auth/multi-factor-auth-required') {
self.resolver = error.resolver;
//assigning to my data field so I can use this later with my phone number verification
console.log(error.resolver);
//UNDEFINED
...
} else {
...
}
});
}
}
In the code above the error object does not have a resolver, so "error.resolver" is undefined which I need in a later stage.
(FYI:- I am not using the Multi-Tenancy option)
UPDATE: Solved
The docs (https://cloud.google.com/identity-platform/docs/web/mfa) are outdated and functions are changed now.
Now the resolver doesn't come from the error object, we just need to call the resolver using a firebase function
getMultiFactorResolver
resolver = getMultiFactorResolver(auth, error);
Have a look here and you will undestand everything: https://firebase.google.com/docs/reference/js/auth.multifactorresolver#example_2
I am trying really hard to make MSAL work with Vanilla JavaScript, but it just doesn't work.
Whenever I am trying to click the Sign In button on the Login Page, the Login page just refreshes and nothing happens, the Microsoft Sign In Page is not being shown.
Also no errors are logged to console.
After clicking the Sign In button for like 200 or more times and page refreshing that many times, the Microsoft Sign In page shows up and then it works fine.
Script reference
<script type="text/javascript" src="https://alcdn.msauth.net/lib/1.4.4/js/msal.js" integrity="sha384-fTmwCjhRA6zShZq8Ow5ZkbWwmgp8En46qW6yWpNEkp37MkV50I/V2wjzlEkQ8eWD" crossorigin="anonymous"></script>
JS MSAL code
//Config
const msalConfig = {
auth: {
clientId: "{Client ID}",
authority: "{Authority}",
redirectUri: "{Base App URL}/Dashboard", //This URL is registered in Microsoft AAD
navigateToLoginRequestUrl: false
},
cache: {
cacheLocation: "localStorage",
storeAuthStateInCookie: true,
}
};
//Login Request Object
const loginRequest = {
scopes: ["User.Read"],
prompt: 'login',
};
//Initialize MSAL
var myMSALObj = new Msal.UserAgentApplication(msalConfig);
myMSALObj.handleRedirectCallback(authRedirectCallBack);
//Handle Callback
function authRedirectCallBack(error, response) {
if (error) {
console.log(error);
} else {
if (response.tokenType === "id_token") {
console.log("id_token acquired at: " + new Date().toString());
if (myMSALObj.getAccount()) {
showWelcomeMessage(myMSALObj.getAccount());
}
} else if (response.tokenType === "access_token") {
console.log("access_token acquired at: " + new Date().toString());
accessToken = response.accessToken;
try {
callMSGraph(graphConfig.graphMailEndpoint, accessToken, updateUI);
} catch (err) {
console.log(err)
}
} else {
console.log("token type is:" + response.tokenType);
}
}
}
$(document).on("click", "#btn-testing-msal", function () {
myMSALObj.loginRedirect(loginRequest);
});
Any help will be appreciated, Thanks in advance
Debug your frontend code like this, just trying to make sure where caused your problem, and it may have some help:
I am using the FacebookAuthProvider by firebase to login my users from my platform.
I'm using react native in expo with firestore and it was working fine till I tried to add in some checks to redirect users to the correct screens after login. There are two different roles (administrators and users) which have to be separate right after the login.
if (/* user is administrator */) {
this.props.navigation.navigate('Admin');
} else {
this.props.navigation.navigate('Main');
}
After adding this method to separate users by there roles, I got this error:
react native TypeError: Cannot read property 'navigation' of undefined
Later I will add some more details (log files etc. as soon as I've learned how to grep them from my locale machine).
For better understanding I put my whole code here (sorry for the bad indentations which lesses the readability):
const auth = firebase.auth();
const firebaseUser = '';
const usersRef = firebase.firestore().collection('users');
async handleFacebookButton() {
const { type, token, } = await Facebook.logInWithReadPermissionsAsync(FACEBOOK_APP_ID, {
permissions: ['public_profile', 'email']
});
if (type === 'success') {
//Firebase credential is created with the Facebook access token.
const credential = firebase.auth.FacebookAuthProvider.credential(token);
auth.signInAndRetrieveDataWithCredential(credential)
.then(function(userCredential) {
newUserCheck = userCredential.additionalUserInfo.isNewUser;
console.log('newUserCheck = ', newUserCheck)
});
this.setState({loggedIn: "You are signed in"})
this.setState({signedIn: true})
console.log('you are signed in');
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
firebaseUser = {name: user.displayName, uid: user.uid, email: user.email}
console.log(firebaseUser.name, ' and ', firebaseUser.uid);
var existingRef = usersRef.doc(firebaseUser.uid);
existingRef.get().then(function(documentSnapshot) {
// check if user is registered
if(documentSnapshot) {
data = documentSnapshot.data();
console.log('existing user exists!!');
// check if user is an administrator
if (data.administrator == true) {
console.log('existing administrator exists!!');
this.props.navigation.navigate('Admin');
} else { this.props.navigation.navigate('Main');
}
}
});
(error => {
console.log('user not accessed: ', error);
});
//User is not yet in firebase database and needs to be saved
// double check that user is a new user
if (newUserCheck == true) {
this.ref
.doc(uid)
.set({
id: firebaseUser.uid,
username: firebaseUser.name,
email: firebaseUser.email,
})
this.props.navigation.navigate('ChooseRoute')
}
}
})
}
// If login type is not success:
(error => {
this.setState({loggedIn: "Login failed: log in again"})
this.setState({ errorMessage: error.message });
});
}
I fixed it!! 3 days later - it was a binding issue - after several unsuccessful attempts to work out which were the right parts of the functions to bind I converted both 'auth().onAuthStateChanged' and 'documentSnapshot' into fat arrow functions and the errors are gone!! Thank goodness for ES6...! Hope this helps someone else down the line...
I created logins and unique todo lists per user using Firebase and TodoMVC as proof of concept for another project. I'm using Firebase and Google to log users in and when things are working, they get a unique persistent todo list.
Everything works (I think) when the user is already logged into Google via their browser.
The problem happens when they aren't. Instead of their todo list, or a blank one under their user id, they see the todo list of an undefined user until they hit refresh, then things work again. The Firebase url doesn't see their uid until they hit refresh. If you're logged in to Google, you can replicate the error by opening an incognito window.
You can see the errors in my code at http://lacyjpr.github.io/todo-backbone, and my repo at https://github.com/lacyjpr/todo-backbone
This is my authentication code:
// Authenticate with Google
var ref = new Firebase(<firebase url>);
ref.onAuth(function(authData) {
if (authData) {
console.log("Authenticated successfully");
} else {
// Try to authenticate with Google via OAuth redirection
ref.authWithOAuthRedirect("google", function(error, authData) {
if (error) {
console.log("Login Failed!", error);
}
});
}
})
// Create a callback which logs the current auth state
function authDataCallback(authData) {
if (authData) {
console.log("User " + authData.uid + " is logged in with " + authData.provider);
uid = authData.uid;
} else {
console.log("User is logged out");
}
}
This is the code that gets the UID to use as a firebase key:
// Get the uid of the user so we can save data on a per user basis
var ref = new Firebase(<firebase url>);
var authData = ref.getAuth();
if (authData) {
var uid = authData.uid;
console.log(uid);
}
// The collection of todos is backed by firebase instead of localstorage
var TodoList = Backbone.Firebase.Collection.extend({
// Reference to this collection's model.
model: app.Todo,
// Save all of the todos to firebase
url: <firebase url> + uid,
Thanks in advance for any advice you can offer!
You're calling .getAuth() before a user is authenticated.
Your app heavily relies on the uid to work properly. So in your case you would want to kick off the Backbone portion of the app once user has successfully authenticated.
You could modify your app.js to only kick off if the user is authenticated.
// js/app.js
var app = app || {};
var ENTER_KEY = 13;
$(function() {
var ref = new Firebase(<firebase url>);
var authData = ref.getAuth();
if (authData) {
ref.authWithOAuthRedirect("google", function(error, authData) {
if (error) {
console.log("Login Failed!", error);
} else {
// kick off app
new app.AppView();
}
});
} else {
new app.AppView();
}
});
While this will work, it isn't the ideal solution. But there is no other option since you don't have a login screen.
Ideally, you'd want to provide the user a place to login, and then you'd have access the .getAuth() value.
Also, don't worry about storing the uid on the window. .getAuth() is the cached user, so there's no network call to get the data.
I am trying to use Firebase's Facebook authentication on a webpage, but I get this error:
Login failed Error: Invalid authentication credentials provided.
at Error (native)
at http://45.55.203.213/js/firebase.js:160:367
at e (http://45.55.203.213/js/firebase.js:140:400)
Here's my Javascript code:
var ref = new Firebase("https://fantasy-smash-bros.firebaseio.com/");
function FBLogin() {
ref.authWithOAuthPopup("facebook", function(error, authData) {
if (error) {
console.log("Login failed", error);
} else {
loginWithAuthData(authData);
}
});
}
function loginWithAuthData(authData) {
username = authData.facebook.displayName;
avatarURL = authData.facebook.cachedUserProfile.picture.data.url;
userID = authData.facebook.id;
}
function attemptLogin() {
var user = ref.getAuth();
if (user) {
loginWithAuthData(user);
} else {
$("#fb-login").click(function () {
FBLogin();
});
}
}
$(document).ready(function () {
attemptLogin();
});
Note: I have imported firebase.js. Here's a copy of the Javascript I used.
I believe I have setup everything correctly: adding Firebase's callback URL to my Facebook app's whitelist, enabling Facebook authentication on the Firebase app. But I am still stumped on what to do. Any help would be greatly appreciated.