How the user authorization is done using Firebase in a webapp? - javascript

I've got following code for user authorization using Firebase but I'm not able to understand the code. Below the code I've mentioned the doubts I'm facing. Plase someone clarify them.
var ref = new Firebase("https://prj_name.firebaseio.com");
var loggedInUser = [];
$(document).ready(function() {
authData=ref.getAuth();
if(authData == null){
//TODO find an elegant way to manage authorization
// window.location = "../index.html";
}else{
ref.child("users").child(authData.uid).on("value", function(snapshot){
$( "span.user-name").html(snapshot.val().displayName);
loggedInUser.displayName = snapshot.val().displayName;
});
}
$("#cPassword").focusout(function() {
validatePassword($("#cPassword"), $("#password"));
});
$(document).on("click", ".clickable-row" ,function(){
window.document.location = $(this).data("href");
});
});
function validatePassword(password, cPassword) {
if (cPassword.val() != password.val()) {
cPassword.css('border-color', 'red');
password.css('border-color', 'red');
return false;
}
return true;
}
All the necessary libraries like firebase have been included and above code is working absolutely fine, the only concern is I'm not able to understand it.
My doubts are as follows :
What does the line authData=ref.getAuth(); do and what authData contains after it get execute?
In else block, what is value and snapshot. I didn't understand at all the line. ref.child("users").child(authData.uid).on("value", function(snapshot)
Can someone please clarify my doubts? Thanks.

Ok here goes:
Firstly you should update your firebase security rules first if you haven't already: Firebase security rules guide
ref.getAuth() returns a value that will either be null if you haven't been authorised yet or it will contain an object with some info about how the user was authorised (custom token, facebook id, email etc.)
This line: ref.child("users").child(authData.uid).on("value", function(snapshot). Here you're basically requesting some data from your users collection: '/users/{some unique id}'. When you request the data from firebase, as soon as the data is ready to be used, Firebase triggers the "value" callback and passes the data (snapshot) using this callback.
The firebase docs are very good, I would advise reading through the entire web guide. Firebase web guide
I hope I've been able to clear some things up for you!

Related

Firebase One on One Chat

I am trying to create a one to one chat on a global firebase chat. I was wondering how would I proceed to do it? What I am doing now is that I created another HTML file which is where the private chats would happen and I am searching by users id
with this piece of code.
oneOnone.addEventListener('click', function(e){
// Attach an asynchronous callback to read the data at our posts reference
ref.on("value", function (snapshot) {}, function (errorObject) {
console.log("The read failed: " + errorObject.code);
});
ref.orderByChild("userId").on("child_added", function (snapshot) {
console.log(snapshot.val().userId);
console.log(searchId);
if(searchId.value === snapshot.val().userId){
window.location.href = 'privatemessage.html';
}
});
});
This then leads into the privatemessage.html file where all the chats should happen. The feeling I have been having is that my database might not right.
The database on firebase still registers people as it would in a Global chat, not a 1 on 1 chat. I am just completely confused on how to make sure the chat would be between only two people. If someone could recommend a guide, give a full fledged explanation on how 1v1 chat would work that would be appreciated. Yes I have look at the docs, it really does not explain how to do a 1v1 chat.
Edit
So I have changed up my database to this
So what I am leaning on is something like this for the one on one talk
var pmChat = database.ref('chat/' + userId);
Basically creating a new reference and then linking the userid but now, how I link the userid of the other user?
you can link current user id with the other userid like this:
database.ref('chat').child(currentUserId).child(otherUserId).child(message);
database.ref('chat').child(otherUserId).child(currentUserId).child(message);

Creating a user session - NODE js

I am new to node js & javascript in general. I have the below piece of code that will handle a login. I have a MYSQL database with a customer table. When the customer enters their username and password, it checks does it exist in the database. This part is working.
I now want to enhance this feature so that it will take the username and create some sort of a session variable, which can be used across the application. I am new to JS so I am not yet sure which inbuilt facilities already exist, or best practice around sessions.
I want to be able to use this session variable across the application, and for subsequent logout facility.
Can someone advise me on this, or point me in the right direction? Thanks.
case "/login":
var body = '';
console.log("user Login ");
request.on('data', function (data) {
body += data;
});
request.on('end', function () {
var obj = JSON.parse(body);
console.log(JSON.stringify(obj, null, 2));
var query = "SELECT * FROM Customer where name='"+obj.name+"'";
response.writeHead(200, {
'Access-Control-Allow-Origin': '*'
});
db.query(
query,
[],
function(err, rows) {
if (err) {
response.end('{"error": "1"}');
throw err;
}
if (rows!=null && rows.length>0) {
console.log(" user in database" );
theuserid = rows[0].customerID;
var obj = {
id: theuserid
}
response.end(JSON.stringify(obj));
}
else{
response.end('{"error": "1"}');
console.log(" user not in database");
}
}
);
});
}
There can be multiple ways of implementing a user session.
One, you could use a browser cookie, it comes with many pros and cons and you should read about it a bit to see how its managed. This would also depend on the server you are using (express, hapi, etc).
Two, you can set a JWT token on the backend, and include it in the header of the response, then you can either use your application state or the local storage of the browser to save that token on the UI. Any such follow up requests requiring authentication should contain this auth token as a header for verification.
For more clarity, you can look into related libraries (such as passport), which make this task a lot easier.
PS: If you choose cookies, please make sure the business is going to allow it or not as the end-users do not like being tracked always. :)

firebase javascript injection

I want ask something about firebase security. How to handle following situations?
User is creating account with createUserWithEmailAndPassword() function, then i save his username,email,created_at...to realtime db. But what if data are not saved correctly. His account is created and he is logged in automatically but data is not stored.
I have some registration logic... for example unique usernames... so before creating acc i check if this username exist in realtime db. But he still can call createUserWithEmailandPassword() from js console and account is created.
For situation one:
According to the firebase docs (https://www.firebase.com/docs/web/api/firebase/createuser.html), creating a user does not automatically authenticate them. An additional call to authWithPassword() is required first. In order to ensure that a user isn't authenticated without valid data, you could run a check to the server to make sure the data is saved correctly before authenticating.
Edit: Nevermind that; looks like firebase does auto-auth now - take a look at what I wrote below.
Now a concern with this approach would be if your app allowed people to authenticate with an OAuth provider like gmail, then there is no function for creating the user before authenticating them. What you may need to do is pull the user data from the firebase, determine if it's valid, and if its not valid show a popup or redirect that lets the user fix any invalid data.
For situation two:
If you wanted to make sure that in the case of them calling createUserWithEmailAndPassword() from the console a new user is not created, you could try something like this with promises;
var createUserWithEmailAndPassword = function(username, password) {
var promise = isNewUserValid(username, password);
promise.then(function() {
// Code for creating new user goes here
});
}
In this way, you never expose the actual code that makes a new user because it exists within an anonymous function.
I don't think that this could solve the problem entirely though because firebases API would let anyone create an account using something
var ref = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com");
ref.createUser({
email: "bobtony#firebase.com",
password: "correcthorsebatterystaple"
}
(Taken from https://www.firebase.com/docs/web/api/firebase/createuser.html)
If you wanted to make sure that server side you can't ever create a user with the same user name, you'd need to look into firebases's rules, specifically .validate
Using it, you could make sure that the username doesn't already exist in order to validate the operation of creating a username for an account.
Here's the firebase doc on rules: https://www.firebase.com/docs/security/quickstart.html
And this is another question on stack overflow that is quite similar to yours. Enforcing unique usernames with Firebase simplelogin Marein's answer is a good starting point for implementing the server side validation.
First save the user credentials in the realtime database before you create the user:
var rootRef = firebase.database().ref('child');
var newUser = {
[name]: username,
[email]: useremail,
[joined]: date
};
rootRef.update(newUser);
After adding the Usersinfo into the realtime database create a new user:
firebase.auth().createUserWithEmailAndPassword(useremail, userpassword).catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
// ...
});
When an error occured while inserting the data in the realtime database, it will skip the createuser function.
This works fine for me, hope this helps!

hello.js, get access token (or anything at all)

I'm trying to use hello.js to allow users to login using their social media accounts. I seem to be successfully getting the allow page to show, and a redirect is happening but I don't understand how my system is supposed to know who that person is. I'm assuming it's via the access token but I can't seem to print it to the console at any point of the login process.
$('#facebookLogin').on('click', function(e){
e.preventDefault();
hello('facebook').login({display:'page'});
return false;
});
This "works" as in, I see the app connected in my Facebook apps. I've tried to follow the instructions here in order to show the object after login but I see nothing with console.log(token).
$('#facebookLogin').on('click', function(e){
e.preventDefault();
hello( 'facebook' ).login({display: 'page'} function() {
var token = hello( 'facebook' ).getAuthResponse().access_token;
console.log(token);
});
return false;
});
I humbly request that if you have answer to post working code. There's a lot of text trying to explain this and I really don't understand it. I need to see something that works.
Try this code.
$('#facebookLogin').on('click', function(event) {
event.preventDefault();
hello('facebook').login({display: 'page'},
function() {
hello('facebook').api("me")
.then(function(userDetails) {
console.log("hello api success");
console.log(userDetails);
}, function(e) {
console.log(e);
});
});
return false;
});
userDetails contains user credentials.
Hope it helps.

How to handle user information using firebase simple login for facebook

I am building a webpage using AngularJS and Firebase. I want to use facebook login to connect information on the webpage with the user. Firebase has a version of simple login which I guess is supposed to simplify the login process.
My problem is that I want to access information about the logged in user in a lot of places on my webpage but I can't find a good way to do it.
This is how I started out:
var userInfo = null;
var ref = new Firebase('https://<yourfirebase>.firebaseIO.com/');
var auth = new FirebaseSimpleLogin(ref, function(error, user) {
if(error)
alert("You are not logged in");
else if(user)
{
//store userinfo in variable
userInfo = user;
}
else
//user logged out
});
//do something with userInfo
alert(userInfo.name);
My first thought was to run this at the top of my page and then use the info about the user. The problem is that the code using userInfo (as in e.g. the alert) will always run before the userInfo variable has been filled and userInfo will return undefined/null.
I then proceeded to always create a new firebasesimplelogin object when i want to retrieve user data. Which of course isn't very good. Especially since every created FirebaseSimpleLogin object will be called again whenever another is called or a user logs out, for example.
So my question is, how do I use FirebaseSimpleLogin to handle and use my user information in the best way?
I would have liked some function to getUserInfo() or check isLoggedIn() for example. How do you do this properly?
You can take a look at this example for thinkster. It's based on using simple login with userid/password. http://www.thinkster.io/angularjs/4DYrJRxTyT/7-creating-your-own-user-data-using-firebase.
You can create a function like getLoggedinUser that runs in $rootScope that will allow you to find the user throughout the application.
UPDATE:
Around the middle of October 2014, firebase made some big changes. This method might still work, but it's better to take advantage of the newer version of firebase, specifically getauth and onauth. These methods will allow you to do the same thing without running on the rootScope. https://www.firebase.com/docs/web/guide/user-auth.html#section-login
Please make a constant to use it everywhere in your App like that
.constant('facebookUrl', 'https://rjrestaurantapp.firebaseio.com');
Then in the controller inject this constant "facebookUrl & "$state" as shown below...
.controller('loginCtrl', function($scope,facebookUrl,$state){
and then you only need to give name of the state where you want to redirect after facebook authentication..
var ref = new Firebase(facebookUrl);
$scope.fbLogin = function () {
ref.authWithOAuthPopup("facebook", function(error, authData) {
if (error) {
console.log("Login Failed!", error);
} else {
console.log("Authenticated successfully with payload:", authData);
$state.go('restaurant');
}
})
}})
You can see the information in authData object after successfull authentication using facebook ....
please read this doc carefully https://www.firebase.com/docs/web/guide/login/facebook.html
The above is the example of simple login using firebase and for retrieving data for each logged in user, you have to store user information at the time of signin as you know that firebase makes every child with a unique ID .. then you only need to use the offline features of firebase that will find which user is offline and according to that remove the node with the same ID which one is offline, you can find examples in the MANAGING PRESENCE section of the below link ..
https://www.firebase.com/docs/web/guide/offline-capabilities.html

Categories