Firebase 身份验证需要两次“登录"调用 [英] Firebase Authentication Requires Two 'Login' Calls

查看:27
本文介绍了Firebase 身份验证需要两次“登录"调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为我的 Web 应用程序硬编码一个身份验证层,以便我可以查看用户是否是管理员".如果我不在登录函数之前放置if 语句",则登录有效.但是当我添加它时,它需要我按两次登录按钮才能工作.

登录功能:

function login() {var userEmail = document.getElementById("email_field").value;var userPass = document.getElementById("password_field").value;var 登录 = [];var usersRef = firebase.database().ref("停车场");usersRef.orderByChild("admin").on("value", function (snapshot) {快照.forEach(函数(子快照){var childData = childSnapshot.val();login.push(childData.admin);});});firebase.auth().setPersistence(firebase.auth.Auth.Persistence.SESSION).then(函数(){如果(登录.包括(用户电子邮件)){返回 firebase.auth().signInWithEmailAndPassword(userEmail, userPass);}}).catch(函数(错误){window.alert("失败");var errorCode = error.code;var errorMessage = error.message;});}

HTML 登录按钮:

我做了一些研究,对其他人来说,当你设置按钮 type="button" 时它起作用了,但它对我不起作用.

<h3>Firebase Web 登录示例</h3><input type="email" placeholder="Email..." id="email_field"/><input type="password" placeholder="密码..." id="password_field"/><button type="button" onclick="login()">登录账户</button>

新的工作登录功能:

function login() {var userEmail = document.getElementById("email_field").value;var userPass = document.getElementById("password_field").value;var 登录 = [];var usersRef = firebase.database().ref("停车场");返回 usersRef.orderByChild("admin").once("value").then(function (snapshot) {快照.forEach(函数(子快照){var childData = childSnapshot.val();login.push(childData.admin);});如果(登录.包括(用户电子邮件)){firebase.auth().setPersistence(firebase.auth.Auth.Persistence.SESSION).then(函数(){返回 firebase.auth().signInWithEmailAndPassword(userEmail, userPass);}).catch(函数(错误){window.alert("密码错误");var errorCode = error.code;var errorMessage = error.message;});}别的 {window.alert("请输入其他邮箱");}});}

解决方案

on() 是异步的,并在数据库发生任何事情之前立即返回.您传递给 on() 的回调的第一个响应完全有可能在调用 signInWithEmailAndPassword 之后触发.您可能应该使用 once() 代替,并在尝试处理其查询结果之前使用它返回的承诺.此外,您应该使用 once() 因为我强烈怀疑您不希望每次给定位置的数据更改时都继续调用该侦听器.

I'm trying to hard code an authentication layer for my web app, so I can see whether a user is an 'admin' or not. The login works if I do not put the 'if statement' before the sign in function. But when I add it, it requires me to press the login button twice before it works.

Login Function:

function login() {
  var userEmail = document.getElementById("email_field").value;
  var userPass = document.getElementById("password_field").value;
  var login = [];
  var usersRef = firebase.database().ref("Parking Lots");
  usersRef.orderByChild("admin").on("value", function (snapshot) {
    snapshot.forEach(function (childSnapshot) {
      var childData = childSnapshot.val();
      login.push(childData.admin);
    });
  });
  firebase.auth().setPersistence(firebase.auth.Auth.Persistence.SESSION)
    .then(function () {
      if(login.includes(userEmail)){
       return firebase.auth().signInWithEmailAndPassword(userEmail, userPass);
      }
    })
    .catch(function (error) {
      window.alert("Fail");
      var errorCode = error.code;
      var errorMessage = error.message;
    });
}

HTML Login Button:

I did some research and for others it worked when you set the button type="button", but it does not work for me.

<div id="login_div" class="main-div">
    <h3>Firebase Web login Example</h3>
    <input type="email" placeholder="Email..." id="email_field" />
    <input type="password" placeholder="Password..." id="password_field" />
    <button type="button" onclick="login()">Login to Account</button>
  </div>

Edit: New Working Login Function:

function login() {
  var userEmail = document.getElementById("email_field").value;
  var userPass = document.getElementById("password_field").value;
  var login = [];

  var usersRef = firebase.database().ref("Parking Lots");
  return usersRef.orderByChild("admin").once("value").then(function (snapshot) {
    snapshot.forEach(function (childSnapshot) {
      var childData = childSnapshot.val();
      login.push(childData.admin);
    });
    if(login.includes(userEmail)){
      firebase.auth().setPersistence(firebase.auth.Auth.Persistence.SESSION)
      .then(function () {
        return firebase.auth().signInWithEmailAndPassword(userEmail, userPass);
      })
      .catch(function (error) {
        window.alert("Password incorrect");
        var errorCode = error.code;
        var errorMessage = error.message;
      });
    }
    else {
      window.alert("Please enter another email");
    }
  });
}

解决方案

on() is asynchronous and returns immediately, before anything happens with the database. It's entirely possible that the first response from the callback you pass to on() could trigger after the call to signInWithEmailAndPassword. You should probably be using once() instead, and use the promise it returns before trying to process the results of its query. Also, you should be using once() because I strongly suspect you don't want that listener to keep getting invoked every time the data at the given location changes.

这篇关于Firebase 身份验证需要两次“登录"调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆