@@ -63,17 +63,17 @@ Localized versions of the widget are available through the CDN. To use a localiz
6363localized JS library instead of the default library:
6464
6565``` html
66- <script src =" https://www.gstatic.com/firebasejs/ui/2.5.1 /firebase-ui-auth__{LANGUAGE_CODE}.js" ></script >
67- <link type =" text/css" rel =" stylesheet" href =" https://www.gstatic.com/firebasejs/ui/2.5.1 /firebase-ui-auth.css" />
66+ <script src =" https://www.gstatic.com/firebasejs/ui/2.6.0 /firebase-ui-auth__{LANGUAGE_CODE}.js" ></script >
67+ <link type =" text/css" rel =" stylesheet" href =" https://www.gstatic.com/firebasejs/ui/2.6.0 /firebase-ui-auth.css" />
6868```
6969
7070where ` {LANGUAGE_CODE} ` is replaced by the code of the language you want. For example, the French
7171version of the library is available at
72- ` https://www.gstatic.com/firebasejs/ui/2.5.1 /firebase-ui-auth__fr.js ` . The list of available
72+ ` https://www.gstatic.com/firebasejs/ui/2.6.0 /firebase-ui-auth__fr.js ` . The list of available
7373languages and their respective language codes can be found at [ LANGUAGES.md] ( LANGUAGES.md ) .
7474
7575Right-to-left languages also require the right-to-left version of the stylesheet, available at
76- ` https://www.gstatic.com/firebasejs/ui/2.5.1 /firebase-ui-auth-rtl.css ` , instead of the default
76+ ` https://www.gstatic.com/firebasejs/ui/2.6.0 /firebase-ui-auth-rtl.css ` , instead of the default
7777stylesheet. The supported right-to-left languages are Arabic (ar), Farsi (fa), and Hebrew (iw).
7878
7979### Option 2: npm Module
@@ -129,6 +129,9 @@ FirebaseUI includes the following flows:
129129by default.)
1301306 . [ Account Chooser] ( https://www.accountchooser.com/learnmore.html?lang=en ) for
131131remembering emails
132+ 7 . Integration with
133+ [ one-tap sign-up] ( https://developers.google.com/identity/one-tap/web/overview )
134+ 8 . Ability to upgrade anonymous users through sign-in/sign-up.
132135
133136### Configuring sign-in providers
134137
@@ -203,6 +206,18 @@ for a more in-depth example, showcasing a Single Page Application mode.
203206</html >
204207```
205208
209+ When redirecting back from accountchooser.com or Identity Providers like Google
210+ and Facebook, ` start() ` method needs to be called to finish the sign-in flow.
211+ To check if there is a pending redirect operation to complete a sign-in attempt,
212+ check ` isPendingRedirect() ` before deciding whether to render FirebaseUI
213+ via ` start() ` .
214+
215+ ``` javascript
216+ if (ui .isPendingRedirect ()) {
217+ ui .start (' #firebaseui-auth-container' , uiConfig);
218+ }
219+ ```
220+
206221Here is how you would track the Auth state across all your pages:
207222
208223``` html
@@ -284,6 +299,19 @@ FirebaseUI supports the following configuration parameters.
284299</thead >
285300<tbody >
286301<tr >
302+ <td >autoUpgradeAnonymousUsers</td >
303+ <td >No</td >
304+ <td >
305+ Whether to automatically upgrade existing anonymous users on sign-in/sign-up.
306+ See <a href =" #upgrading-anonymous-users " >Upgrading anonymous users</a >.
307+ <br />
308+ <em >Default:</em >
309+ <code >false</code >
310+ When set to <code >true</code >, <code >signInFailure</code > callback is
311+ required to be provided to handle merge conflicts.
312+ </td >
313+ </tr >
314+ <tr >
287315<td >callbacks</td >
288316<td >No</td >
289317<td >
@@ -594,6 +622,29 @@ static `signInSuccessUrl` in config.
594622If the callback returns ` false ` or nothing, the page is not automatically
595623redirected.
596624
625+ #### ` signInFailure(error) `
626+
627+ The ` signInFailure ` callback is provided to handle any unrecoverable error
628+ encountered during the sign-in process.
629+ The error provided here is a ` firebaseui.auth.AuthUIError ` error with the
630+ following properties.
631+
632+ ** firebaseui.auth.AuthUIError properties:**
633+
634+ | Name | Type | Optional | Description |
635+ | ---------| ----------------| ---------| -----------------------|
636+ | ` code ` | ` string ` | No | The corresponding error code. Currently the only error code supported is ` firebaseui/anonymous-upgrade-merge-conflict ` |
637+ | ` credential ` | ` firebase.auth.AuthCredential ` | Yes | The existing non-anonymous user credential the user tried to sign in with.|
638+
639+ ** Should return: ` Promise<void>|void ` **
640+
641+ FirebaseUI will wait for the returned promise to handle the reported error
642+ before clearing the UI. If no promise is returned, the UI will be cleared on
643+ completion. Even when this callback resolves, ` signInSuccess ` callback will not
644+ be triggered.
645+
646+ This callback is required when ` autoUpgradeAnonymousUsers ` is enabled.
647+
597648#### ` uiShown() `
598649
599650This callback is triggered the first time the widget UI is rendered. This is
@@ -624,6 +675,14 @@ FirebaseUI is displayed.
624675 // or whether we leave that to developer to handle.
625676 return true ;
626677 },
678+ signInFailure : function (error ) {
679+ // Some unrecoverable error occurred during sign-in.
680+ // Return a promise when error handling is completed and FirebaseUI
681+ // will reset, clearing any UI. This commonly occurs for error code
682+ // 'firebaseui/anonymous-upgrade-merge-conflict' when merge conflict
683+ // occurs. Check below for more details on this.
684+ return handleUIError (error);
685+ },
627686 uiShown : function () {
628687 // The widget is rendered.
629688 // Hide the loader.
@@ -677,6 +736,130 @@ FirebaseUI is displayed.
677736</html >
678737```
679738
739+ ### Upgrading anonymous users
740+
741+ #### Enabling anonymous user upgrade
742+
743+ When an anonymous user signs in or signs up with a permanent account, you want
744+ to be sure the user can continue with what they were doing before signing up.
745+ For example, an anonymous user might have items in their shopping cart.
746+ At check-out, you prompt the user to sign in or sign up. After the user is
747+ signed in, the user's shopping cart should contain any items the user added
748+ while signed in anonymously.
749+
750+ To support this behavior, FirebaseUI makes it easy to "upgrade" an anonymous
751+ account to a permanent account. To do so, simply set ` autoUpgradeAnonymousUsers `
752+ to ` true ` when you configure the sign-in UI (this option is disabled by
753+ default).
754+
755+ FirebaseUI links the new credential with the anonymous account using Firebase
756+ Auth's ` linkWithCredential ` method:
757+ ``` javascript
758+ anonymousUser .linkWithCredential (permanentCredential);
759+ ```
760+ The user will retain the same ` uid ` at the end of the flow and all data keyed
761+ on that identifier would still be associated with that same user.
762+
763+ #### Handling anonymous user upgrade merge conflicts
764+
765+ There are cases when a user, initially signed in anonymously, tries to
766+ upgrade to an existing Firebase user. For example, a user may have signed up
767+ with a Google credential on another device. When trying to upgrade to the
768+ existing Google user, an error ` auth/credential-already-in-use ` will be thrown
769+ by Firebase Auth as an existing user cannot be linked to another existing user.
770+ No two users can share the same credential. In that case, both user data
771+ have to be merged before one user is discarded (typically the anonymous user).
772+ In the case above, the anonymous user shopping cart will be copied locally,
773+ the anonymous user will be deleted and then the user is signed in with the
774+ permanent credential. The anonymous user data in temporary storage will be
775+ copied back to the non-anonymous user.
776+
777+ FirebaseUI will trigger the ` signInFailure ` callback with an error code
778+ ` firebaseui/anonymous-upgrade-merge-conflict ` when the above occurs. The error
779+ object will also contain the permanent credential.
780+ Sign-in with the permanent credential should be triggered in the callback to
781+ complete sign-in.
782+ Before sign-in can be completed via
783+ ` auth.signInWithCredential(error.credential) ` , the data of the anonymous user
784+ must be copied and the anonymous user deleted. After sign-in completion, the
785+ data has to be copied back to the non-anonymous user. An example below
786+ illustrates how this flow would work if user data is persisted using Firebase
787+ Realtime Database.
788+
789+ ** Example:**
790+
791+ ``` javascript
792+ // Temp variable to hold the anonymous user data if needed.
793+ var data = null ;
794+ // Hold a reference to the anonymous current user.
795+ var anonymousUser = firebase .auth ().currentUser ;
796+ ui .start (' #firebaseui-auth-container' , {
797+ // Whether to upgrade anonymous users should be explicitly provided.
798+ // The user must already be signed in anonymously before FirebaseUI is
799+ // rendered.
800+ autoUpgradeAnonymousUsers: true ,
801+ signInSuccessUrl: ' <url-to-redirect-to-on-success>' ,
802+ signInOptions: [
803+ firebase .auth .GoogleAuthProvider .PROVIDER_ID ,
804+ firebase .auth .FacebookAuthProvider .PROVIDER_ID ,
805+ firebase .auth .EmailAuthProvider .PROVIDER_ID ,
806+ firebase .auth .PhoneAuthProvider .PROVIDER_ID
807+ ],
808+ callbacks: {
809+ signInSuccess : function (user , credential , redirectUrl ) {
810+ // Process result. This will not trigger on merge conflicts.
811+ // On success redirect to signInSuccessUrl.
812+ return true ;
813+ },
814+ // signInFailure callback must be provided to handle merge conflicts which
815+ // occur when an existing credential is linked to an anonymous user.
816+ signInFailure : function (error ) {
817+ // For merge conflicts, the error.code will be
818+ // 'firebaseui/anonymous-upgrade-merge-conflict'.
819+ if (error .code != ' firebaseui/anonymous-upgrade-merge-conflict' ) {
820+ return Promise .resolve ();
821+ }
822+ // The credential the user tried to sign in with.
823+ var cred = error .credential ;
824+ // If using Firebase Realtime Database. The anonymous user data has to be
825+ // copied to the non-anonymous user.
826+ var app = firebase .app ();
827+ // Save anonymous user data first.
828+ return app .database ().ref (' users/' + firebase .auth ().currentUser .uid )
829+ .once (' value' )
830+ .then (function (snapshot ) {
831+ data = snapshot .val ();
832+ // This will trigger onAuthStateChanged listener which
833+ // could trigger a redirect to another page.
834+ // Ensure the upgrade flow is not interrupted by that callback
835+ // and that this is given enough time to complete before
836+ // redirection.
837+ return firebase .auth ().signInWithCredential (cred);
838+ })
839+ .then (function (user ) {
840+ // Original Anonymous Auth instance now has the new user.
841+ return app .database ().ref (' users/' + user .uid ).set (data);
842+ })
843+ .then (function () {
844+ // Delete anonymnous user.
845+ return anonymousUser .delete ();
846+ }).then (function () {
847+ // Clear data in case a new user signs in, and the state change
848+ // triggers.
849+ data = null ;
850+ // FirebaseUI will reset and the UI cleared when this promise
851+ // resolves.
852+ // signInSuccess will not run. Successful sign-in logic has to be
853+ // run explicitly.
854+ window .location .assign (' <url-to-redirect-to-on-success>' );
855+ });
856+
857+ }
858+ }
859+ });
860+ ```
861+
862+
680863## Customizing FirebaseUI for authentication
681864
682865Currently, FirebaseUI does not offer customization out of the box. However, the
@@ -762,6 +945,18 @@ where `{LANGUAGE_CODE}` is replaced by the
762945can be built with ` npm run build build-js-fr ` . This will create a binary
763946` firebaseui__fr.js ` in the ` dist/ ` folder.
764947
948+ To build a localized npm FirebaseUI module, run:
949+ ``` bash
950+ npm run build build-npm-{LANGUAGE_CODE}
951+ ```
952+ Make sure all underscore symbols in the ` LANGUAGE_CODE ` are replaced with
953+ dashes.
954+ This will generate ` dist/npm__{LANGUAGE_CODE}.js ` .
955+ You can then import/require it:
956+ ``` javascript
957+ import firebaseui from ' ./npm__{LANGUAGE_CODE}' ;
958+ ```
959+
765960### Running the demo app
766961
767962To run the demo app, you must have a Firebase project set up on the
0 commit comments