Displaying text after login - firebase

I am designing a math problem site using Firebase and I want to display a problem when someone logs in.
What I want in pseudo code is,
if user logged in
document.write([problem])
else
document.write(Please login to see the problem)
Any ideas?

When using Firebase Simple Login, upon instantiation of the FirebaseAuthClient you will define a callback function that is invoked any time the login state of the user changes.
From https://www.firebase.com/docs/security/simple-login-overview.html:
var chatRef = new Firebase('https://SampleChat.firebaseIO-demo.com');
var authClient = new FirebaseAuthClient(chatRef, function(error, user) {
if (user) {
// user authenticated with Firebase
} else if (error) {
// an error occurred authenticating the user
} else {
// user is logged out
}
});
For your case, if you have a user object, you can hide any login-related UI and show the problem, otherwise, hide the problem and show any login-related UI.
Then, to log users in, choose one or more of the Firebase Simple Login authentication providers, configure that provider in Forge (accessed via https://<your-firebase>.firebaseio.com) and attempt to authenticate the user via:
authClient.login(<provider>, <options>);
I hope that helps!

Related

Sending Verification email to existing users

I am working on a web app with an existing user base. Email verification was not initially implemented in the sign in flow.
I have successfully added code for sending verification email for all new sign ups but I also wanted to make a small page (or modal) where current users would be shown a button that would send the verification link to their inbox
The current sign up flow where I created the user with createUserWithEmailAndPassword I was able to get access to the user.user.sendEmailVerification method to do so, but cannot find any way to access this method to implement the feature for existing users.
Is there a way to access the sendEmailVerification method after the user has been created?
I am assuming that it would be available within the onAuthStateChange trigger but implementing that would lead to a bad UX (as I do not want to prompt the users everytime they login)
Edit:
I know the documentation states that we can use the firebase.auth().currentUser to get the current user but that, for some reason did not work.
Also, I found references online suggesting to no longer use that method and they mentioned to use the onAuthStateChange method instead, which is why I was looking into that approach
You can try this method:
const btnVerifyEmail = document.getElementById("btn-verify-id")
btnVerifyEmail.onclick = function () {
const user = firebase.auth().currentUser;
user.sendEmailVerification().then(function() {
// Email sent.
console.log("Email Sent")
}).catch(function(error) {
// An error happened.
console.log(error)
});
}
It's mentioned in the documentation right here
The sendEmailVerification() should not be called in the onAuthStateChanged event because it would blast out an email on every page load if the user's email isn't verified.
You should instead display a notification on the page if User.emailVerified is false that contains a link to send the user an email.
Here's a working example:
// On page load watch for auth state changes
firebase.auth().onAuthStateChanged(function(user) {
// If the user is logged in
if (user) {
// If the user's email isn't verified
if (!user.emailVerified) {
// Show the notification bar that informs the user that they need to validate
// their email by clicking a link. Let's pretend the link looks like this:
// Send me a verification email
showNotification();
}
}
});
// Function attached to your link's onclick event
function sendEmailVerification() {
// Retrieve the current user
const user = firebase.auth().currentUser;
// If user's email is already verified, exit
if (user.emailVerified) {
return;
}
// Tell Firebase to send the verification email and discard the promise
user.sendEmailVerification().then().catch();
}
Dharmaraj's answer is good but this is a full example.

Flutter Web and Firebase authentication: how to redirect not logged in user in flutter web?

I'm developing a web app using Flutter Web and Firebase.
I have to handle the Firebase Login.
Let's assume we have two screens, the situation that I want to achieve is the following:
if the user is not logged in:
Redirect the user on the login page
If the user is not logged in:
if he lands on the login page, redirect him on the homepage
I've implemented a functions that checks the current user in firebase and acts as following:
void checkAuthentication() {
var url = window.location.href;
var navigationService = locator<NavigationService>();
var loggedIn = this.isUserLoggedIn();
if (!loggedIn) {
navigationService.replaceWith(Routes.login);
} else {
if (url.contains("Login")) {
navigationService.replaceWith(Routes.homepage);
}
}
}
the navigationService is a service I took from the stacked package (https://pub.dev/packages/stacked).
This solution works, but has two problems:
this is not the right approach to do this. It's not possible that I have to call this in each screen page
When you are redirected you can see a transition with the new page presented.
My question:
How would you manage this in Flutter Web in a unique point in the code?
Is there a better way to achieve this differnt from the one I shown here?
If you have the time checkout the first couple videos from The Net Ninja's Flutter/Firebase tutorial which go over basic authentication. I am pretty new to Flutter so I'll try my best to explain how he does it without going into detail:
He has a file wrapper.dart which uses a custom User object which constantly streams the authentication state. The wrapper decides where the user should navigate depending on authentication state.
Widget build(BuildContext context) {
final user = Provider.of<User>(context);
print(user);
// return either home or authenticate
if (user == null) {
return Authenticate();
} else {
return Home();
}
}
I am using this code in my project and it works well.

How to determine whether it's a SignUp or SignIn in Passwordless Auth from Firebase? [duplicate]

My use case is that I want to ask newly signed up users to enrich basic info like their names.
So I was hoping to do it like:
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
// User is signed in.
if (some indicator tells me it is newly signed up user)
{redirect to a form to fill in more info}
} else {
// No user is signed in.
}
});
I checked the doc, and could not find anything related to this...
Thanks for the help in advance.
Since version 4.6.0: https://firebase.google.com/support/release-notes/js#4.6.0
You can get if a user is new or existing in 2 ways:
If you are getting back a UserCredential result, check result.additionalUserInfo.isNewUser
Check firebase.auth().currentUser.metadata.creationTime === firebase.auth().currentUser.metadata.lastSignInTime
Previously you had to do that on your own and keep track of the user using Firebase Realtime Database. When a user signs in, you check if a user with the specified uid exists in the database or not. If the user was not found, it is a new user, you can then add the user to the database. If the user is already in the database then this is a returning existing user. Here is an example in iOS.
Handing Firebase + Facebook login process
Example for using result.additionalUserInfo.isNewUser:
firebase.auth().signInWithPopup(provider).then((result) => {
console.log(result.additionalUserInfo.isNewUser);
});
One thing you can do is do things in the callback function of the signup function, the signup function do return a promise. You can do something like this:
firebase.auth().createUserWithEmailAndPassword(email, password)
.then(function(user) {
//I believe the user variable here is the same as firebase.auth().currentUser
//take the user to some form you want them to fill
})
.catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
// ...
});
However, I don't really recommend doing it this way because the client side code can be unreliable. Think about what if a user suddenly disconnect before they can fill the form. Their data will be incomplete in your database. So if you do it this way, do set a flag in your user's profile when they submit the form so that you know who filled detailed information and who didn't.
Another better way to do this is using firebase cloud functions. You can have code like this in your cloud functions. Cloud functions are written in node.js so you don't need to spend time on another language.
exports.someoneSignedUp = functions.auth.user().onCreate(event => {
// you can send them a cloud function to lead them to the detail information form
//or you can send them an welcome email which will also lead them to where you want them to fill detailed information
});
This way is much better because you can safely assume that your cloud functions server will never be down or compromised. For more information about cloud functions you can refer to their doc: https://firebase.google.com/docs/functions/auth-events
You can check the sign-in methods the user has (if any). If there are none, it is a new user.
// Fetch sign in methods (if any)
Auth.auth().fetchSignInMethods(forEmail: userEmail!) { [self] signInMethodsArray, error in
// Check for error and alert user accordingly
if let error = error {
// handle errors
}
// Email accepted.
// Check if new or returning user.
else {
if (signInMethodsArray == nil) {
// New User
}
else {
// Returning User
}
}
}
This is Swift (iOS) code, but the concept is the same across languages.

Best way to force user to log in before accessing my website

I'm getting started with Firebase and I would like to have a suggestion concerning the best way to force a user to be logged to use my website.
I'm building a very simple app but i have to guarantee that content can be displayed only to logged people
Thank you!
Use auth().onAuthStateChanged
https://firebase.google.com/docs/auth/web/start#set_an_authentication_state_observer_and_get_user_data
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
// User is signed in.
var displayName = user.displayName;
var email = user.email;
var emailVerified = user.emailVerified;
var photoURL = user.photoURL;
var isAnonymous = user.isAnonymous;
var uid = user.uid;
var providerData = user.providerData;
// ...
} else {
// User is signed out.
// ...
}
});
I assume you are using PHP to build your firebase website, in php there are session tokens that can be used to auto log in. once you got a session login you could use that to redirect them to the login page if they are not logged in. here a snip of code from one of my old college projects.
if(!isset($_SESSION['user_logged_in'])){
header("Location: ../login.php");
}else{
if($_SESSION['user_logged_in'] != true){
header("Location: ../login.php");
}
}
its been a while but this checks if I remember correctly the first line checks if there is no session token and the second line checks to see if that person is logged in. if either of this isn't true it will load the login page instead of the page they wanted and cause its all done in php they can't get around this. we put all this in an authentication template, I have uploaded the PHP file to google drive if you wish to example how logins are done, this is using an MYOB database so you will have to convert it but the code in here should be a good example.
https://drive.google.com/open?id=1_oKWU3LnpmfJg2pD5kHzYxFX2Ydl42e_
hope this helps

Firebase Auth, how to know new user signed up, rather than existing user sign in?

My use case is that I want to ask newly signed up users to enrich basic info like their names.
So I was hoping to do it like:
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
// User is signed in.
if (some indicator tells me it is newly signed up user)
{redirect to a form to fill in more info}
} else {
// No user is signed in.
}
});
I checked the doc, and could not find anything related to this...
Thanks for the help in advance.
Since version 4.6.0: https://firebase.google.com/support/release-notes/js#4.6.0
You can get if a user is new or existing in 2 ways:
If you are getting back a UserCredential result, check result.additionalUserInfo.isNewUser
Check firebase.auth().currentUser.metadata.creationTime === firebase.auth().currentUser.metadata.lastSignInTime
Previously you had to do that on your own and keep track of the user using Firebase Realtime Database. When a user signs in, you check if a user with the specified uid exists in the database or not. If the user was not found, it is a new user, you can then add the user to the database. If the user is already in the database then this is a returning existing user. Here is an example in iOS.
Handing Firebase + Facebook login process
Example for using result.additionalUserInfo.isNewUser:
firebase.auth().signInWithPopup(provider).then((result) => {
console.log(result.additionalUserInfo.isNewUser);
});
One thing you can do is do things in the callback function of the signup function, the signup function do return a promise. You can do something like this:
firebase.auth().createUserWithEmailAndPassword(email, password)
.then(function(user) {
//I believe the user variable here is the same as firebase.auth().currentUser
//take the user to some form you want them to fill
})
.catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
// ...
});
However, I don't really recommend doing it this way because the client side code can be unreliable. Think about what if a user suddenly disconnect before they can fill the form. Their data will be incomplete in your database. So if you do it this way, do set a flag in your user's profile when they submit the form so that you know who filled detailed information and who didn't.
Another better way to do this is using firebase cloud functions. You can have code like this in your cloud functions. Cloud functions are written in node.js so you don't need to spend time on another language.
exports.someoneSignedUp = functions.auth.user().onCreate(event => {
// you can send them a cloud function to lead them to the detail information form
//or you can send them an welcome email which will also lead them to where you want them to fill detailed information
});
This way is much better because you can safely assume that your cloud functions server will never be down or compromised. For more information about cloud functions you can refer to their doc: https://firebase.google.com/docs/functions/auth-events
You can check the sign-in methods the user has (if any). If there are none, it is a new user.
// Fetch sign in methods (if any)
Auth.auth().fetchSignInMethods(forEmail: userEmail!) { [self] signInMethodsArray, error in
// Check for error and alert user accordingly
if let error = error {
// handle errors
}
// Email accepted.
// Check if new or returning user.
else {
if (signInMethodsArray == nil) {
// New User
}
else {
// Returning User
}
}
}
This is Swift (iOS) code, but the concept is the same across languages.

Resources