5
votes

I'm trying to set up Firebase authentication with email, but I click on the login button and I get this error:

users.js:15 Uncaught TypeError: Cannot read property 'value' of null

It's also sending me to another page (the home page after hitting the login button). Here is a link to the documentation for how to set up the authentication.

Javascript:

var config = {
    apiKey: "",
    authDomain: "",
    databaseURL: "",
    projectId: "",
    storageBucket: "",
    messagingSenderId: ""
};

firebase.initializeApp(config);

//var emailTxt = document.getElementById("emailTxt").value;
//var email = emailTxt.val();
//var password = passwordTxt.val();



$('#login').on("click", function(){
  var email = document.getElementById('emailTxt').value;
  var password = document.getElementById('passwordTxt').value;
  authClient.login("password", {
  email: $("#email").val(),
  password: $("#password").val(),
  rememberMe: $("#rememberCheckbox").val()
  });

});

firebase.auth().createUserWithEmailAndPassword(email, password).catch(function(error) {
    // Handle Errors here.
    alert();
    var errorCode = error.code;
    var errorMessage = error.message;
    // ...
});

firebase.auth().signInWithEmailAndPassword(email, password).catch(function(error) {
    // Handle Errors here.
    var errorCode = error.code;
    var errorMessage = error.message;
    // ...
});

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.
        // ...
    }
});

firebase.auth().signOut().then(function() {
    // Sign-out successful.
}).catch(function(error) {
    // An error happened.
});

HTML:

<?php
    //CREATE USER
?>

<!DOCTYPE html>
<html>
    <head>
        <title>Cheapest Used Tires</title>
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css"
              integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ" crossorigin="anonymous">
        <script src="https://code.jquery.com/jquery-3.1.1.slim.min.js"
                integrity="sha384-A7FZj7v+d/sdmMqp/nOQwliLvUsJfDHW+k9Omg/a/EheAdgtzNs3hpfag6Ed950n"
                crossorigin="anonymous"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js"
                integrity="sha384-DztdAPBWPRXSA/3eYEEUWrWCy7G5KFbe8fFjk5JAIxUYHKkDx6Qin1DkWx51bBrb"
                crossorigin="anonymous"></script>
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js"
                integrity="sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn"
                crossorigin="anonymous"></script>

    </head>
    <style>
        form {
            border: 3px solid #f1f1f1;
        }

        input[type=text], input[type=password] {
            width: 100%;
            padding: 12px 20px;
            margin: 8px 0;
            display: inline-block;
            border: 1px solid #ccc;
            box-sizing: border-box;
        }

        button {
            background-color: #4CAF50;
            color: white;
            padding: 14px 20px;
            margin: 8px 0;
            border: none;
            cursor: pointer;
            width: 100%;
        }

        button:hover {
            opacity: 0.8;
        }

        .cancelbtn {
            width: auto;
            padding: 10px 18px;
            background-color: #f44336;
        }

        .imgcontainer {
            text-align: center;
            margin: 24px 0 12px 0;
        }

        img.avatar {
            width: 40%;
            border-radius: 50%;
        }

        .container {
            padding: 16px;
        }

        span.psw {
            float: right;
            padding-top: 16px;
        }

        /* Change styles for span and cancel button on extra small screens */
        @media screen and (max-width: 300px) {
            span.psw {
                display: block;
                float: none;
            }
            .cancelbtn {
                width: 100%;
            }
        }
    </style>
    </head>
    <body>

        <h2>Login</h2>

        <form action="/CMS/login.php">
            <div class="imgcontainer">
                <img src="img_avatar2.png" alt="Cheapest Used Tires Admin Logn" 
                    class="avatar">
            </div>

            <div class="container">
                <label><b>Email</b></label>
                <input id="emailTxt" type="text" 
                    placeholder="Enter Email" name="email" required>

                <label><b>Password</b></label>
                <input id="passwordTxt" type="password" 
                    placeholder="Enter Password" name="psw" required>

                <button type="submit" id="login">Login</button>
                <input type="checkbox" checked="checked"> Remember me
            </div>

            <div class="container" style="background-color:#f1f1f1">
                <button type="button" class="cancelbtn">Cancel</button>
                <span class="psw">Forgot 
                    <a href="#">password?</a>
                </span>
                <span class="psw">&nbsp; | &nbsp; </span>
                <span class="psw">Create 
                    <a href="#">account?</a>
                </span>

            </div>
        </form>

        <script src="https://www.gstatic.com/firebasejs/4.6.2/firebase.js"></script>
        <script src="/users.js"></script>

    </body>
</html>
6
doesnt look like firebase issue..maybe one of var email = document.getElementById('emailTxt').value; var password = document.getElementById('passwordTxt').value; is nullSuraj Rao
i think that the declaration of email and password should be placed inside the onclick listener. otherwise the value is reading when the page is loaded and they are null before the user insert his credentials.Ami Hollander
@Ami Hollander - I just tried that and it did not work. I edited this question with email and password inside of the onClick listener.Ryder Thacker
Please see provided answer.Vipin Kumar

6 Answers

1
votes

The problem raise because you are using undefined arguments such as email and password outside the relevant scope.

You have two options:

  1. use document.getElementById inside callback to retrieve the values. (example 1)

  2. call a function with the values. (example 2)

Note: Declaring the firebase functions calls like you did raise exception because they are called with undefined arguments

$('#login').on("click", function(){
    // example 1
    var email = document.getElementById('emailTxt').value;
    var password = document.getElementById('passwordTxt').value;

    // email and password are defined
    firebase.auth().signInWithEmailAndPassword(email, password).catch(function(error) {
        // Handle Errors here.
        var errorCode = error.code;
        var errorMessage = error.message;
        // ...
    });
});

// example 2
function createUser(email, password) {
    firebase.auth().createUserWithEmailAndPassword(email, password).catch(function(error) {
        // Handle Errors here.
        alert();
        var errorCode = error.code;
        var errorMessage = error.message;
        // ...
    });
}


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.
        // ...
    }
});

function logout() {
    firebase.auth().signOut().then(function() {
        // Sign-out successful.
    }).catch(function(error) {
        // An error happened.
    });
}
1
votes

You are moving away from the page before the call returns.

The default behavior of Submit button (when clicked) is to POST the form. You have to prevent that from happening. (because you are posting values throught AJAX)

use event.preventDefault()

$('#login').on("click", function(event){

  event.preventDefault();

  var email = document.getElementById('emailTxt').value;
  var password = document.getElementById('passwordTxt').value;
  authClient.login("password", {
  email: $("#email").val(),
  password: $("#password").val(),
  rememberMe: $("#rememberCheckbox").val()
  });
1
votes

I am not getting any error i just created a fiddle with your html and i changed the JavaScript. I can console the value entered by the user.

$('#login').on("click", function(event) {
  event.preventDefault();

  var email = document.getElementById('emailTxt').value;
  var password = document.getElementById('passwordTxt').value;
  console.log($("#rememberCheckbox").is(":checked"));
  console.log(email);
  console.log(password);
  authClient.login("password", {
    email: email,
    password: password,
    rememberMe: $("#rememberCheckbox").is(":checked")
  });
})

check the fiddle https://jsfiddle.net/suhailsulu/ezzxd1th/2/

1
votes

Add id to your form tag. Then attach on("submit") event handler. Also, fix ids in JQuery selector in object your are passing to authClient.login.

Problems:

  1. id mismatch at email: $("#email").val() and password: $("#password").val(), they should be email: $("#emailTxt").val() and password: $("#passwordTxt").val()
  2. HTML doesn't contain any checkbox with this id="rememberCheckbox". Add this in your HTML.
  3. On click of Login button, form is getting posted to php page and you are not preventing it. Event handler should be attached to form submit event and add e.preventDefault(), which will prevent redirection(post back).

Please see below:

$('#myForm').on("submit", function(e) {
  e.preventDefault();
  authClient.login("password", {
    email: $("#emailTxt").val(),
    password: $("#passwordTxt").val(),
    rememberMe: $("#rememberCheckbox").val()
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="myForm">
  <button type="submit" id="login">Login</button>
</form>
1
votes

Make sure button is of type="button". The default is type="submit" which means the form will be submitted.

Or better - have a onsubmit listener on the form instead of a click listener on the button. And make sure you prevent the default (submitting the form).

Or just don't use form elements ... Forms are a relic from the days before JavaScript. It's default action is to make a HTTP Get request with the form's data in the query string. You could change the action to "post" and it would make a http post instead, with the form's data in the request body instead of querystring. This was added because query strings has a size limit.

0
votes

Please follow the below code which I have learned through the Firebase tutorial at the link https://www.youtube.com/watch?v=-OKrloDzGpU

The Logout button is set to be hidden and once the user signs up and logs in the logout button is set to visible in the onAuthStateChanged method.

Here is the below implementation of what you are trying to achieve,

Below is the app.js code what you are trying to acheive in users.js code :

(function(){
              // Initialize Firebase
              var config = {
                apiKey: "",
                authDomain: "",
                databaseURL: "",
                projectId: "",
                storageBucket: "",
                messagingSenderId: ""
              };
              firebase.initializeApp(config);


              //Get all the elements 
              const txtEmail= document.getElementById('txtEmail');
               const txtPassword= document.getElementById('txtPassword');
                const btnLogin= document.getElementById('btnLogin');
                 const btnSignUp= document.getElementById('btnSignUp');
                  const btnLogout= document.getElementById('btnLogout');


                  //Add the Login Event 
                  btnLogin.addEventListener('click', e=>{
                      //Get the email and password
                      const email = txtEmail.value;
                      const pass = txtPassword.value;
                      const auth = firebase.auth();
                      //Sign in
                      const promise = auth.signInWithEmailAndPassword(email, pass);
                      promise.catch(e => console.log(e.message));

            });
             //Add the signup event
             btnSignUp.addEventListener('click', e=>{
                 console.log('in signup now');
                  //Get the email and password
                      const email = txtEmail.value;
                      const pass = txtPassword.value;
                      const auth = firebase.auth();
                      //Sign in
                      const promise = auth.createUserWithEmailAndPassword(email, pass);
                      promise.catch(e => console.log(e.message));

             });

              btnLogout.addEventListener('click', e=>{
                  firebase.auth().signOut();
              });

             //Add a realtime listener 
             firebase.auth().onAuthStateChanged(firebaseUser => {
                if(firebaseUser)
                {
                 console.log(firebaseUser);
                 btnLogout.classList.remove('hide');
                }
                else
                {
                 console.log(firebaseUser);
                 console.log('not logged in');
                 btnLogout.classList.add('hide');
                }
             });





            }());

HTML:

<!DOCTYPE html>
        <html>
            <head>
            <meta charset="utf-8">
            <title> Login System </title>
            <meta charset="utf-8">

            <link href="https://fonts.googleapis.com/css?family=Roboto:300,500" rel="stylesheet">
            <script src="https://www.gstatic.com/firebasejs/4.6.2/firebase.js"></script>
            <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">

            </head>
            <body>

            <div class="container">
            <div class="row" style="margin-top:20px">
            <div class="col-xs-14 col-sm-11 col-md-11 col-sm-offset-2 col-md-offset-3">
                <fieldset>
                <br>
                <div class="col-md-4">
                <h2>Please Sign In </h2>
                </div>
                <br>
                <br>
                <br>
                <br>
                  <div class="col-md-4">
                  <input id="txtEmail" name="Email" type="email" placeholder="Email" class="form-control input-md">
                  </div>
                <br>
                <br>
                <div class="col-md-4">
                <input id="txtPassword" name="Pasword" type="Password" placeholder="Password" class="form-control input-md">
                </div>
                <br>
                <br>
                <div class="col-xs-6 col-sm-6 col-md-6">
                <button id="btnLogin" class="btn btn-action">
                Log in
                </button>
                <button id="btnSignUp" class="btn btn-secondary">
                Sign Up
                </button>
                <button id="btnLogout" class="btn btn-action hide">
                Log Out
                </button>
                </div>
            </fieldset>
            </div>
            </div>
            </div>
                <script src="app.js"></script>
            </body>
        </html>