FirebaseUI 是建構於 Firebase Authentication SDK 之上的程式庫,可提供可隨插即用的 UI 流程,供您在應用程式中使用。FirebaseUI 提供下列優點:
- 多個供應商:電子郵件/密碼、電子郵件連結、電話驗證、Google、Facebook、Twitter 和 GitHub 的登入流程。
- 帳戶連結:跨身分識別服務供應商安全連結使用者帳戶的流程。
- 自訂:覆寫 FirebaseUI 的 CSS 樣式,以符合應用程式需求。此外,由於 FirebaseUI 是開放原始碼,您可以分支專案並視需求自訂。
- 一鍵註冊和自動登入:自動整合一鍵註冊,快速跨裝置登入。
- 本地化使用者介面:支援超過 40 種語言的國際化功能。
- 升級匿名使用者:可透過登入/註冊升級匿名使用者。詳情請參閱「升級匿名使用者」一節。
事前準備
在網頁應用程式中加入 Firebase 驗證功能,請務必使用第 9 版或更新版本的命名空間 API (不是模組化 API;請參閱上述側欄)。
透過下列任一選項加入 FirebaseUI:
CDN
在頁面的 <head> 標記中,將下列指令碼和 CSS 檔案加入 Firebase 控制台的初始化程式碼片段下方:
<script src="https://www.gstatic.com/firebasejs/ui/6.0.1/firebase-ui-auth.js"></script> <link type="text/css" rel="stylesheet" href="https://www.gstatic.com/firebasejs/ui/6.0.1/firebase-ui-auth.css" />
npm 模組
使用下列指令,透過 npm 安裝 FirebaseUI 及其依附元件:
$ npm install firebaseui --save
require
來源檔案中的下列模組:var firebase = require('firebase'); var firebaseui = require('firebaseui');
Bower 元件
使用下列指令,透過 Bower 安裝 FirebaseUI 及其依附元件:
$ bower install firebaseui --save
如果 HTTP 伺服器提供
bower_components/
中的檔案,請在 HTML 中加入必要的檔案:<script src="bower_components/firebaseui/dist/firebaseui.js"></script> <link type="text/css" rel="stylesheet" href="bower_components/firebaseui/dist/firebaseui.css" />
初始化 FirebaseUI
匯入 SDK 後,請初始化 Auth UI。
// Initialize the FirebaseUI Widget using Firebase.
var ui = new firebaseui.auth.AuthUI(firebase.auth());
設定登入方式
您必須先啟用並設定要支援的登入方法,才能使用 Firebase 讓使用者登入。
電子郵件地址和密碼
在 Firebase 控制台中,開啟「驗證」部分,並啟用電子郵件和密碼驗證機制。
將電子郵件供應器 ID 新增至 FirebaseUI
signInOptions
清單。ui.start('#firebaseui-auth-container', { signInOptions: [ firebase.auth.EmailAuthProvider.PROVIDER_ID ], // Other config options... });
選用:您可以設定
EmailAuthProvider
,要求使用者輸入顯示名稱 (預設為true
)。ui.start('#firebaseui-auth-container', { signInOptions: [ { provider: firebase.auth.EmailAuthProvider.PROVIDER_ID, requireDisplayName: false } ] });
電子郵件連結驗證
在 Firebase 主控台中,開啟「驗證」部分。在「Sign in method」分頁中,啟用「Email/Password」提供者。請注意,您必須啟用電子郵件/密碼登入功能,才能使用電子郵件連結登入功能。
在同一個部分中,啟用「電子郵件連結 (不需要密碼即可登入)」登入方式,然後按一下「儲存」。
將電子郵件供應器 ID 與電子郵件連結
signInMethod
一併新增至 FirebaseUIsignInOptions
清單。ui.start('#firebaseui-auth-container', { signInOptions: [ { provider: firebase.auth.EmailAuthProvider.PROVIDER_ID, signInMethod: firebase.auth.EmailAuthProvider.EMAIL_LINK_SIGN_IN_METHOD } ], // Other config options... });
在條件式轉譯登入 UI 時 (適用於單頁應用程式),請使用
ui.isPendingRedirect()
偵測網址是否對應至含有電子郵件連結的登入畫面,以及是否需要轉譯 UI 才能完成登入程序。// Is there an email link sign-in? if (ui.isPendingRedirect()) { ui.start('#firebaseui-auth-container', uiConfig); } // This can also be done via: if (firebase.auth().isSignInWithEmailLink(window.location.href)) { ui.start('#firebaseui-auth-container', uiConfig); }
選用:您可以設定電子郵件連結登入的
EmailAuthProvider
,允許或禁止使用者完成跨裝置登入。您可以定義選用的
emailLinkSignIn
回呼,以便在傳送連結時傳回要使用的firebase.auth.ActionCodeSettings
設定。這可讓您指定連結的處理方式、自訂動態連結、深層連結中的其他狀態等。如果未提供,系統會使用目前的網址,並觸發僅限網頁的流程。FirebaseUI-web 中的電子郵件連結登入功能與 FirebaseUI-Android 和 FirebaseUI-iOS 相容,如果使用者透過 FirebaseUI-Android 啟動流程,就能開啟連結並透過 FirebaseUI-web 完成登入程序。反向流程也是如此。
ui.start('#firebaseui-auth-container', { signInOptions: [ { provider: firebase.auth.EmailAuthProvider.PROVIDER_ID, signInMethod: firebase.auth.EmailAuthProvider.EMAIL_LINK_SIGN_IN_METHOD, // Allow the user the ability to complete sign-in cross device, // including the mobile apps specified in the ActionCodeSettings // object below. forceSameDevice: false, // Used to define the optional firebase.auth.ActionCodeSettings if // additional state needs to be passed along request and whether to open // the link in a mobile app if it is installed. emailLinkSignIn: function() { return { // Additional state showPromo=1234 can be retrieved from URL on // sign-in completion in signInSuccess callback by checking // window.location.href. url: 'https://www.example.com/completeSignIn?showPromo=1234', // Custom FDL domain. dynamicLinkDomain: 'example.page.link', // Always true for email link sign-in. handleCodeInApp: true, // Whether to handle link in iOS app if installed. iOS: { bundleId: 'com.example.ios' }, // Whether to handle link in Android app if opened in an Android // device. android: { packageName: 'com.example.android', installApp: true, minimumVersion: '12' } }; } } ] });
OAuth 供應商 (Google、Facebook、Twitter 和 GitHub)
在 Firebase 主控台中,開啟「Authentication」部分,並啟用指定的 OAuth 供應商登入功能。請務必一併指定對應的 OAuth 用戶端 ID 和密碼。
在「驗證」部分中,請確認要轉譯登入頁面的網域也已加入授權網域清單。
將 OAuth 供應器 ID 新增至 FirebaseUI
signInOptions
清單。ui.start('#firebaseui-auth-container', { signInOptions: [ // List of OAuth providers supported. firebase.auth.GoogleAuthProvider.PROVIDER_ID, firebase.auth.FacebookAuthProvider.PROVIDER_ID, firebase.auth.TwitterAuthProvider.PROVIDER_ID, firebase.auth.GithubAuthProvider.PROVIDER_ID ], // Other config options... });
選用:如要指定自訂權限或每個供應者的自訂 OAuth 參數,您可以傳遞物件,而非僅傳遞供應者值:
ui.start('#firebaseui-auth-container', { signInOptions: [ { provider: firebase.auth.GoogleAuthProvider.PROVIDER_ID, scopes: [ 'https://www.googleapis.com/auth/contacts.readonly' ], customParameters: { // Forces account selection even when one account // is available. prompt: 'select_account' } }, { provider: firebase.auth.FacebookAuthProvider.PROVIDER_ID, scopes: [ 'public_profile', 'email', 'user_likes', 'user_friends' ], customParameters: { // Forces password re-entry. auth_type: 'reauthenticate' } }, firebase.auth.TwitterAuthProvider.PROVIDER_ID, // Twitter does not support scopes. firebase.auth.EmailAuthProvider.PROVIDER_ID // Other providers don't need to be given as object. ] });
電話號碼
在 Firebase 控制台中,開啟「驗證」部分,並啟用電話號碼登入功能。
請確認要轉譯登入頁面的網域也已加入授權網域清單。
將電話號碼供應商 ID 新增至 FirebaseUI
signInOptions
清單。ui.start('#firebaseui-auth-container', { signInOptions: [ firebase.auth.PhoneAuthProvider.PROVIDER_ID ], // Other config options... });
選用:PhoneAuthProvider 可使用自訂 reCAPTCHA 參數進行設定,決定 reCAPTCHA 是否顯示 (預設為正常)。詳情請參閱 reCAPTCHA API 說明文件。
您也可以設定在電話號碼輸入畫面中選取的預設國家/地區。如需完整的代碼清單,請參閱支援的國家/地區代碼清單。如果未指定,電話號碼輸入值會預設為美國 (+1)。
目前支援下列選項。
ui.start('#firebaseui-auth-container', { signInOptions: [ { provider: firebase.auth.PhoneAuthProvider.PROVIDER_ID, recaptchaParameters: { type: 'image', // 'audio' size: 'normal', // 'invisible' or 'compact' badge: 'bottomleft' //' bottomright' or 'inline' applies to invisible. }, defaultCountry: 'GB', // Set default country to the United Kingdom (+44). // For prefilling the national number, set defaultNationNumber. // This will only be observed if only phone Auth provider is used since // for multiple providers, the NASCAR screen will always render first // with a 'sign in with phone number' button. defaultNationalNumber: '1234567890', // You can also pass the full phone number string instead of the // 'defaultCountry' and 'defaultNationalNumber'. However, in this case, // the first country ID that matches the country code will be used to // populate the country selector. So for countries that share the same // country code, the selected country may not be the expected one. // In that case, pass the 'defaultCountry' instead to ensure the exact // country is selected. The 'defaultCountry' and 'defaultNationaNumber' // will always have higher priority than 'loginHint' which will be ignored // in their favor. In this case, the default country will be 'GB' even // though 'loginHint' specified the country code as '+1'. loginHint: '+11234567890' } ] });
登入
如要啟動 FirebaseUI 登入流程,請傳遞基礎 Auth
例項,初始化 FirebaseUI 例項。
// Initialize the FirebaseUI Widget using Firebase.
var ui = new firebaseui.auth.AuthUI(firebase.auth());
定義要轉譯 FirebaseUI 登入小工具的 HTML 元素。
<!-- The surrounding HTML is left untouched by FirebaseUI.
Your app may use that space for branding, controls and other customizations.-->
<h1>Welcome to My Awesome App</h1>
<div id="firebaseui-auth-container"></div>
<div id="loader">Loading...</div>
指定 FirebaseUI 設定 (支援的供應商、UI 自訂選項,以及成功回呼等)。
var uiConfig = {
callbacks: {
signInSuccessWithAuthResult: function(authResult, redirectUrl) {
// User successfully signed in.
// Return type determines whether we continue the redirect automatically
// or whether we leave that to developer to handle.
return true;
},
uiShown: function() {
// The widget is rendered.
// Hide the loader.
document.getElementById('loader').style.display = 'none';
}
},
// Will use popup for IDP Providers sign-in flow instead of the default, redirect.
signInFlow: 'popup',
signInSuccessUrl: '<url-to-redirect-to-on-success>',
signInOptions: [
// Leave the lines as is for the providers you want to offer your users.
firebase.auth.GoogleAuthProvider.PROVIDER_ID,
firebase.auth.FacebookAuthProvider.PROVIDER_ID,
firebase.auth.TwitterAuthProvider.PROVIDER_ID,
firebase.auth.GithubAuthProvider.PROVIDER_ID,
firebase.auth.EmailAuthProvider.PROVIDER_ID,
firebase.auth.PhoneAuthProvider.PROVIDER_ID
],
// Terms of service url.
tosUrl: '<your-tos-url>',
// Privacy policy url.
privacyPolicyUrl: '<your-privacy-policy-url>'
};
最後,轉譯 FirebaseUI Auth 介面:
// The start method will wait until the DOM is loaded.
ui.start('#firebaseui-auth-container', uiConfig);
升級匿名使用者
啟用匿名使用者升級功能
當匿名使用者使用永久帳戶登入或註冊時,您必須確保使用者可以繼續執行註冊前的操作。如要這麼做,只要在設定登入 UI 時將 autoUpgradeAnonymousUsers
設為 true
即可 (這個選項預設為停用)。
處理匿名使用者升級合併衝突
在某些情況下,使用者一開始以匿名身分登入,然後嘗試升級為現有的 Firebase 使用者。由於現有使用者無法連結至其他現有使用者,因此當上述情況發生時,FirebaseUI 會觸發 signInFailure
回呼,並附上錯誤代碼 firebaseui/anonymous-upgrade-merge-conflict
。錯誤物件也會包含永久憑證。您應在回呼中觸發使用永久憑證登入的程序,以便完成登入程序。您必須先儲存匿名使用者的資料,並刪除匿名使用者,才能透過 auth.signInWithCredential(error.credential)
完成登入程序。然後在登入完成後,將資料複製回非匿名使用者。以下範例說明此流程的運作方式。
// Temp variable to hold the anonymous user data if needed.
var data = null;
// Hold a reference to the anonymous current user.
var anonymousUser = firebase.auth().currentUser;
ui.start('#firebaseui-auth-container', {
// Whether to upgrade anonymous users should be explicitly provided.
// The user must already be signed in anonymously before FirebaseUI is
// rendered.
autoUpgradeAnonymousUsers: true,
signInSuccessUrl: '<url-to-redirect-to-on-success>',
signInOptions: [
firebase.auth.GoogleAuthProvider.PROVIDER_ID,
firebase.auth.FacebookAuthProvider.PROVIDER_ID,
firebase.auth.EmailAuthProvider.PROVIDER_ID,
firebase.auth.PhoneAuthProvider.PROVIDER_ID
],
callbacks: {
// signInFailure callback must be provided to handle merge conflicts which
// occur when an existing credential is linked to an anonymous user.
signInFailure: function(error) {
// For merge conflicts, the error.code will be
// 'firebaseui/anonymous-upgrade-merge-conflict'.
if (error.code != 'firebaseui/anonymous-upgrade-merge-conflict') {
return Promise.resolve();
}
// The credential the user tried to sign in with.
var cred = error.credential;
// Copy data from anonymous user to permanent user and delete anonymous
// user.
// ...
// Finish sign-in after data is copied.
return firebase.auth().signInWithCredential(cred);
}
}
});
後續步驟
- 如要進一步瞭解如何使用及自訂 FirebaseUI,請參閱 README。
- 如果您在 FirebaseUI 中發現問題,並想要回報,請使用 GitHub Issue Tracker。