Làm cách nào để phát hiện xem người dùng đã đăng nhập vào Firebase chưa?


102

Tôi đang sử dụng api nút firebase trong các tệp javascript của mình để đăng nhập Google.

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

Điều này hoạt động tốt và người dùng có thể đăng nhập bằng thông tin đăng nhập Google của mình. Khi người dùng truy cập lại trang, cửa sổ bật lên sẽ mở lại nhưng vì anh ta đã đăng nhập nên cửa sổ bật lên sẽ đóng lại mà không yêu cầu bất kỳ tương tác nào từ người dùng. Có cách nào để kiểm tra xem đã có người dùng đăng nhập trước khi nhắc cửa sổ bật lên chưa?

Câu trả lời:


113

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

Bạn phải thêm một trình quan sát thay đổi trạng thái xác thực.

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

3
Điều này là không phù hợp với tôi. stackoverflow.com/questions/39395158/…
Dan P.

2
Sử dụng onAuthStateChanged, có cách nào để biết người dùng có phải là người mới không?
Brennan

Có, nhưng không thông qua onAuthStateChanged. Điều này đã được thêm vào 4.6.0: firebase.google.com/support/release-notes/js#4.6.0 Bạn có thể lấy nó từ phương thức đăng nhập hoặc từ currentUser.metadata(thời gian đăng nhập lần cuối và thời gian tạo) ...
bojeil

@bojeil Tôi nghĩ rằng có một cảnh báo đối với phương pháp này. Bạn có thể đặt mã này trên một trang và nó sẽ kích hoạt ngay cả khi bạn không ở trên trang đó. Nó kích hoạt khi AuthState thay đổi. Nếu nó thay đổi trên các trang khác, bạn sẽ kích hoạt nó hiệu quả khi bạn không muốn. Ít nhất, đó là những gì đang xảy ra với tôi lúc này.
thevengefulco

1
Thao tác này sẽ phát hiện các sự kiện đăng nhập trên các tab khác. Nó hoạt động như dự định. Firebase Auth tuyên truyền các sự kiện đăng nhập trên các cửa sổ.
bojeil

82

Bạn cũng có thể kiểm tra nếu có một CurrentUser

var user = firebase.auth().currentUser;

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

8
Điều này sẽ trả về vô hiệu cho tôi ngay cả sau khi đăng nhập ngay lập tức.
Aarmora

8
Thật lạ, nó hoạt động với tôi, có thể vấn đề là do auth không đồng bộ và _ currentUser_ chưa được cập nhật.
Daniel Passos

1
Từ docs: currentUser cũng có thể là null vì đối tượng auth chưa khởi tạo xong. Nếu bạn sử dụng trình quan sát để theo dõi trạng thái đăng nhập của người dùng, bạn không cần phải xử lý trường hợp này.
cheshireoctopus

Bạn không thể dựa vào nó. Xem tài liệu chính thức: "Có một số trường hợp getCurrentUser sẽ trở lại một tổ chức phi-null ..."
Andrew

Nếu bạn nhận được null, có thể là do nó chưa được khởi tạo.
Arnaldo Capo

28

Nó là không thể nói cho dù một người sử dụng sẽ được ký kết khi một trang bắt đầu tải, có một công việc xung quanh mặc dù.

Bạn có thể ghi nhớ trạng thái xác thực cuối cùng vào localStorage để duy trì trạng thái đó giữa các phiên và giữa các tab.

Sau đó, khi trang bắt đầu tải, bạn có thể lạc quan cho rằng người dùng sẽ tự động đăng nhập lại và hoãn hộp thoại cho đến khi bạn có thể chắc chắn (tức là sau khi onAuthStateChangedkích hoạt). Ngược lại, nếu localStoragephím trống, bạn có thể hiển thị hộp thoại ngay lập tức.

Sự onAuthStateChangedkiện firebase sẽ kích hoạt khoảng 2 giây sau khi tải trang.

// 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()
  }
})



Tôi đang sử dụng cái này với Reactreact-router . Tôi đặt mã ở trên vào componentDidMountthành phần gốc Ứng dụng của mình. Ở đó, trong kết xuất, tôi có một sốPrivateRoutes

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

Và đây là cách PrivateRoute của tôi được triển khai:

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}}}
    // />

Bạn có nghĩ rằng bạn có thể giúp tôi với điều này? Tôi đã thử chuyển hướng đăng nhập tự động mà bạn có ở đầu câu trả lời của mình và bây giờ dường như tôi không thể xóa nó. Tôi đã xóa hoàn toàn bộ nhớ cục bộ của mình và tôi vẫn không thể truy cập trang web firebase của mình đã đăng xuất do chuyển hướng liên tục.
hego64

@ hego64 Bạn đã thực sự đăng xuất khỏi ứng dụng firebase của mình chưa? Giải pháp này không thực hiện đăng nhập. Nó chỉ cho phép bỏ qua biểu mẫu đăng nhập nếu người dùng không đăng xuất trong phiên trước. / EDIT: Bạn có đang ở trong vòng lặp chuyển hướng không? Tôi sẽ cập nhật câu trả lời.
Qwerty

Vâng, tôi lẽ ra phải rõ ràng hơn, tôi đã bị mắc kẹt trong một vòng lặp chuyển hướng. Tôi đã đăng xuất và thay vì quay lại ứng dụng, tôi được đưa thẳng trở lại trang đăng nhập. Tôi đã có thể khắc phục nó bằng cách quay lại lần triển khai trước đó, nhưng ngoài việc đó ra, tôi không chắc phải làm gì để khắc phục sự cố.
hego64

1
@ hego64 Người dùng chưa đăng nhập sẽ không thể tự do đi lại trong một ngày, vì vậy chuyển hướng đến trang đăng nhập là đúng, nhưng nếu có các tuyến khả dụng mà không cần xác thực, thì bạn phải di chuyển logic đến bộ định tuyến hoặc các tuyến đường cụ thể thay thế, giống như trong ví dụ về trình bao bọc PrivateRoute của tôi. Vì vậy, nếu người dùng đang ở trên một trang bị hạn chế và đăng xuất, thì họ sẽ được chuyển hướng đến trang đăng nhập. Các tuyến đường khác của bạn sẽ không được triển khai logic này.
Qwerty

Tôi đã bị mắc kẹt về điều này một chút ... phương pháp này hoạt động khá tốt. Cảm ơn bạn.
spetz83

17

Không cần sử dụng hàm onAuthStateChanged () trong trường hợp này.

Bạn có thể dễ dàng phát hiện người dùng đã đăng nhập hay chưa bằng cách thực hiện:

var user = firebase.auth().currentUser;

Đối với những người gặp phải vấn đề "return null", đó chỉ là do bạn không đợi lệnh gọi firebase hoàn tất.

Giả sử bạn thực hiện hành động đăng nhập trên Trang A và sau đó bạn gọi Trang B, trên Trang B, bạn có thể gọi mã JS sau để kiểm tra hành vi mong đợi:

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

Nếu người dùng đã đăng nhập thì "var user" sẽ chứa tải trọng JSON dự kiến, nếu không, thì nó sẽ chỉ là "null"

Và đó là tất cả những gì bạn cần.

Trân trọng


3
@Mauricio Silvestre phải không? Sử dụng firebase.auth.currentUserlợi nhuận undefined hay không Tôi đã đăng nhập Chỉ auth () trả về kết quả chính xác khi đăng nhập..
tsujp

5

Một cách khác là sử dụng cùng một thứ mà firebase sử dụng.

Ví dụ: khi người dùng đăng nhập, firebase lưu trữ các chi tiết bên dưới trong bộ nhớ cục bộ. Khi người dùng quay lại trang, firebase sử dụng cùng một phương pháp để xác định xem người dùng có nên tự động đăng nhập hay không.

nhập mô tả hình ảnh ở đây

ATTN: Vì điều này không được firebase liệt kê hoặc khuyến nghị. Bạn có thể gọi phương pháp này là cách làm không chính thức. Có nghĩa là sau này nếu firebase thay đổi hoạt động bên trong của chúng, phương pháp này có thể không hoạt động. Hay nói ngắn gọn. Sử dụng có nguy cơ của riêng bạn! :)


5

Những công việc này:

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

Nếu bạn đang cho phép những người dùng ẩn danh cũng như những người đã đăng nhập bằng email mà bạn có thể sử dụng firebase.auth().currentUser.isAnonymous, nó sẽ trả về một trong hai truehoặc false.



-3

Đầu tiên nhập những thứ sau

import Firebase
import FirebaseAuth

Sau đó

    // Check if logged in
    if (Auth.auth().currentUser != null) {
      // User is logged in   
    }else{
      // User is not logged in
    }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.