Як визначити, чи користувач вже ввійшов у Firebase?


102

Я використовую API вузла Firebase у своїх файлах javascript для входу в Google.

firebase.initializeApp(config);
let provider = new firebase.auth.GoogleAuthProvider();
firebase.auth().signInWithPopup(provider);

Це працює нормально, і користувач може ввійти в систему зі своїми обліковими даними Google. Коли користувач знову відвідує сторінку, спливаюче вікно відкривається знову, але оскільки він уже ввійшов у систему, спливаюче вікно закривається, не вимагаючи жодної взаємодії з користувачем. Чи є спосіб перевірити, чи вже зареєстрований користувач перед тим, як подавати запит на спливаюче вікно?

Відповіді:


113

https://firebase.google.com/docs/auth/web/manage-users

Ви повинні додати спостерігача зміни стану авторизації.

firebase.auth().onAuthStateChanged(function(user) {
  if (user) {
    // User is signed in.
  } else {
    // No user is signed in.
  }
});

3
Для мене це непослідовно. stackoverflow.com/questions/39395158/…
Ден П.

2
Чи можна за допомогою onAuthStateChanged змінити, чи є користувач новим?
Brennan

Так, але не до кінця onAuthStateChanged. Це було додано в 4.6.0: firebase.google.com/support/release-notes/js#4.6.0 Ви можете отримати його за допомогою методу входу або від currentUser.metadata(час останнього входу та час створення) ...
кольорил

@bojeil Я думаю, що до цього методу є застереження. Ви можете розмістити цей код на одній сторінці, і він спрацює, навіть коли ви не перебуваєте на цій сторінці. Це спрацьовує, коли змінюється AuthState. Якщо воно зміниться на інших сторінках, ви ефективно змусите його спрацьовувати, коли ви цього не хочете. Принаймні, саме це відбувається зі мною зараз.
thevengefulco

1
Це дозволить виявити події входу на інші вкладки. Це працює за призначенням. Firebase Auth розповсюджує події входу у вікна.
bojeil

82

Ви також можете перевірити, чи є currentUser

var user = firebase.auth().currentUser;

if (user) {
  // User is signed in.
} else {
  // No user is signed in.
}

8
Це повертає для мене значення null навіть після негайного входу.
Aarmora,

8
Це дивно, це працює для мене, можливо, проблема полягає в тому, що auth is async і _ currentUser_ ще не оновлений.
Даніель Пассос

1
З документації: currentUser також може бути нульовим, оскільки об’єкт auth не закінчив ініціалізацію. Якщо ви використовуєте спостерігача для відстеження стану входу користувача, вам не потрібно розглядати цю справу.
cheshireoctopus

На нього не можна покластися. Дивіться офіційні документи: "Є деякі випадки, коли getCurrentUser повертає ненульове значення ..."
Ендрю

Якщо ви отримуєте нуль, це, мабуть, тому, що він ще не ініціалізований.
Арнальдо Капо

28

Це неможливо сказати , є чи користувач волі бути підписаний , коли сторінка починається завантаження, є робота навколо , хоча.

Ви можете запам’ятати останній стан авторизації у localStorage, щоб зберігати його між сеансами та між вкладками.

Потім, коли сторінка почне завантажуватися, ви можете оптимістично припустити, що користувач автоматично переввійде в систему і відкласти діалогове вікно, поки ви не будете впевнені (тобто після onAuthStateChanged пожежі). В іншому випадку, якщо localStorageключ порожній, ви можете відразу показати діалогове вікно.

onAuthStateChangedПодія firebase запуститься приблизно через 2 секунди після завантаження сторінки.

// User signed out in previous session, show dialog immediately because there will be no auto-login
if (!localStorage.getItem('myPage.expectSignIn')) showDialog() // or redirect to sign-in page

firebase.auth().onAuthStateChanged(user => {
  if (user) {
    // User just signed in, we should not display dialog next time because of firebase auto-login
    localStorage.setItem('myPage.expectSignIn', '1')
  } else {
    // User just signed-out or auto-login failed, we will show sign-in form immediately the next time he loads the page
    localStorage.removeItem('myPage.expectSignIn')

    // Here implement logic to trigger the login dialog or redirect to sign-in page, if necessary. Don't redirect if dialog is already visible.
    // e.g. showDialog()
  }
})



Я використовую це разом з React та response-router . Я помістив наведений вище код у componentDidMountсвій кореневий компонент програми. Там, у візуалізації, я їх маюPrivateRoutes

<Router>
  <Switch>
    <PrivateRoute
      exact path={routes.DASHBOARD}
      component={pages.Dashboard}
    />
...

І ось як реалізований мій PrivateRoute:

export default function PrivateRoute(props) {
  return firebase.auth().currentUser != null
    ? <Route {...props}/>
    : localStorage.getItem('myPage.expectSignIn')
      // if user is expected to sign in automatically, display Spinner, otherwise redirect to login page.
      ? <Spinner centered size={400}/>
      : (
        <>
          Redirecting to sign in page.
          { location.replace(`/login?from=${props.path}`) }
        </>
      )
}

    // Using router Redirect instead of location.replace
    // <Redirect
    //   from={props.path}
    //   to={{pathname: routes.SIGN_IN, state: {from: props.path}}}
    // />

Думаєш, ти міг би мені в цьому допомогти? Я спробував переадресацію автоматичного входу у вас у верхній частині вашої відповіді, і тепер я не можу видалити його. Я повністю очистив свою локальну пам’ять, і досі не можу отримати доступ до свого сайту Firebase, який вийшов із системи через постійні переспрямування.
hego64

@ hego64 Ви насправді вийшли зі свого додатка Firebase? Це рішення не виконує вхід. Це дозволяє пропустити форму входу, лише якщо користувач не вийшов із системи у попередній сесії. / EDIT: Ви перебуваєте в циклі переспрямування? Я оновлю відповідь.
Qwerty

Так, я повинен був бути більш чітким, я застряг у циклі перенаправлення. Я вийшов із системи і замість того, щоб повернутися до програми, мене повернули прямо на сторінку входу. Я зміг це виправити, повернувшись до попереднього розгортання, але крім цього я не був впевнений, що робити, щоб виправити проблему.
hego64

1
@ hego64 Користувачі, які не ввійшли в систему, не повинні мати змоги вільно ходити навколо, тому переадресація на сторінку входу є правильною, але якщо є маршрути, доступні без автентифікації, вам слід перенести логіку на маршрутизатор або конкретні маршрути, подібно до мого прикладу обгортки PrivateRoute. Отже, якщо користувач перебуває на обмеженій сторінці та виходить із системи, він буде перенаправлений на сторінку входу. На ваших інших маршрутах ця логіка не буде реалізована.
Qwerty

Я трохи затримався на цьому ... цей метод працює досить добре. Дякую.
spetz83

17

У цьому сценарії немає необхідності використовувати функцію onAuthStateChanged ().

Ви можете легко виявити, зареєстрований користувач, чи ні, виконавши:

var user = firebase.auth().currentUser;

Для тих, хто стикається з проблемою "повернення нуля", це просто тому, що ви не чекаєте завершення виклику Firebase.

Припустимо, ви виконуєте дію входу на сторінку A, а потім ви викликаєте сторінку B, на сторінці B ви можете викликати такий код JS для перевірки очікуваної поведінки:

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

    $( document ).ready(function() {
        console.log( "testing.." );
        var user = firebase.auth().currentUser;
        console.log(user);
    });

Якщо користувач зареєстрований, тоді "var user" міститиме очікуване корисне навантаження JSON, якщо ні, то це буде просто "null"

І це все, що вам потрібно.

З повагою


3
@Mauricio Silvestre це? Використання firebase.auth.currentUserповернень undefined незалежно від того, чи я
ввійшов

5

Ще один спосіб - використовувати те саме, що використовує Firebase.

Наприклад, коли користувач входить, firebase зберігає нижче деталі в локальному сховищі. Коли користувач повертається на сторінку, firebase використовує той самий метод, щоб визначити, чи повинен користувач автоматично входити в систему.

введіть тут опис зображення

ATTN: Оскільки це не вказано та не рекомендовано firebase. Ви можете назвати цей метод неофіційним способом. Що означає, що пізніше, якщо firebase змінить свою внутрішню роботу, цей метод може не спрацювати. Або коротше. Використовуйте на свій страх і ризик! :)


5

Це працює:

async function IsLoggedIn(): Promise<boolean> {
  try {
    await new Promise((resolve, reject) =>
      app.auth().onAuthStateChanged(
        user => {
          if (user) {
            // User is signed in.
            resolve(user)
          } else {
            // No user is signed in.
            reject('no user logged in')
          }
        },
        // Prevent console error
        error => reject(error)
      )
    )
    return true
  } catch (error) {
    return false
  }
}

1

Якщо ви дозволяєте анонімним користувачам, а також тим, хто ввійшов у систему електронною поштою, ви можете скористатися ними firebase.auth().currentUser.isAnonymous, які повернуть trueабо false.



-3

Спочатку імпортуйте наступне

import Firebase
import FirebaseAuth

Тоді

    // Check if logged in
    if (Auth.auth().currentUser != null) {
      // User is logged in   
    }else{
      // User is not logged in
    }
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.