Skip to content

Commit 49de7f6

Browse files
wti806bojeil-google
authored andcommitted
- Expose firebase.auth.UserCredential Auth result via new signInWithAuthResult callback. (#352)
PiperOrigin-RevId: 190525518 Change-Id: I63cbb34e93029abcffb4aa76d65bf96c5ef425e0
1 parent c7d3031 commit 49de7f6

File tree

15 files changed

+1345
-122
lines changed

15 files changed

+1345
-122
lines changed

README.md

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -606,8 +606,36 @@ popup is blocked by the browser, it will fall back to a full page redirect.
606606

607607
### Available callbacks
608608

609+
#### `signInSuccessWithAuthResult(authResult, redirectUrl)`
610+
611+
The `signInSuccessWithAuthResult` callback is invoked when user signs in successfully.
612+
The authResult provided here is a `firebaseui.auth.AuthResult` object, which includes the current logged in user, the credential used to sign in the user, additional user info indicating if the user is new or existing and operation type like 'signIn' or 'link'. This callback will replace `signInSuccess` in future.
613+
614+
**Parameters:**
615+
616+
|Name |Type | Optional|Description |
617+
|-------------|------------------------------|---------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
618+
|`authResult`|`firebaseui.auth.AuthResult` |No |The AuthResult of successful sign-in operation. The AuthResult object has same signature as `firebase.auth.UserCredential`.|
619+
|`redirectUrl`|`string` |Yes |The URL where the user is redirected after the callback finishes. It will only be given if you [overwrite the sign-in success URL](#overwriting-the-sign-in-success-url).|
620+
621+
**Should return: `boolean`**
622+
623+
If the callback returns `true`, then the page is automatically redirected
624+
depending on the case:
625+
626+
- If no `signInSuccessUrl` parameter was given in the URL (See:
627+
[Overwriting the sign-in success URL](#overwriting-the-sign-in-success-url))
628+
then the default `signInSuccessUrl` in config is used.
629+
- If the value is provided in the URL, that value will be used instead of the
630+
static `signInSuccessUrl` in config.
631+
632+
If the callback returns `false` or nothing, the page is not automatically
633+
redirected.
634+
609635
#### `signInSuccess(currentUser, credential, redirectUrl)`
610636

637+
This callback will be deprecated and will be replaced by `signInSuccessWithAuthResult` which takes `firebaseui.auth.AuthResult`.
638+
611639
**Parameters:**
612640

613641
|Name |Type | Optional|Description |
@@ -677,7 +705,20 @@ FirebaseUI is displayed.
677705
// FirebaseUI config.
678706
var uiConfig = {
679707
callbacks: {
708+
signInSuccessWithAuthResult: function(authResult, redirectUrl) {
709+
var user = authResult.user;
710+
var credential = authResult.credential;
711+
var isNewUser = authResult.additionalUserInfo.isNewUser;
712+
var providerId = authResult.additionalUserInfo.providerId;
713+
var operationType = authResult.operationType;
714+
// Do something with the returned AuthResult.
715+
// Return type determines whether we continue the redirect automatically
716+
// or whether we leave that to developer to handle.
717+
return true;
718+
},
680719
signInSuccess: function(currentUser, credential, redirectUrl) {
720+
// This callback will be deprecated. `signInSuccessWithAuthResult` should
721+
// be used instead.
681722
// Do something.
682723
// Return type determines whether we continue the redirect automatically
683724
// or whether we leave that to developer to handle.
@@ -814,7 +855,7 @@ ui.start('#firebaseui-auth-container', {
814855
firebase.auth.PhoneAuthProvider.PROVIDER_ID
815856
],
816857
callbacks: {
817-
signInSuccess: function(user, credential, redirectUrl) {
858+
signInSuccessWithAuthResult: function(authResult, redirectUrl) {
818859
// Process result. This will not trigger on merge conflicts.
819860
// On success redirect to signInSuccessUrl.
820861
return true;

demo/public/app.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,15 @@ function getUiConfig() {
2323
return {
2424
'callbacks': {
2525
// Called when the user has been successfully signed in.
26-
'signInSuccess': function(user, credential, redirectUrl) {
27-
handleSignedInUser(user);
26+
'signInSuccessWithAuthResult': function(authResult, redirectUrl) {
27+
if (authResult.user) {
28+
handleSignedInUser(authResult.user);
29+
}
30+
if (authResult.additionalUserInfo) {
31+
document.getElementById('is-new-user').textContent =
32+
authResult.additionalUserInfo.isNewUser ?
33+
'New User' : 'Existing User';
34+
}
2835
// Do not redirect.
2936
return false;
3037
}

demo/public/index.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<meta charset="UTF-8">
55
<title>FirebaseUI Auth Demo</title>
66
<link rel="manifest" href="manifest.json">
7-
<script src="https://www.gstatic.com/firebasejs/live/4.3/firebase.js"></script>
7+
<script src="https://www.gstatic.com/firebasejs/live/4.8/firebase.js"></script>
88
<script src="config.js"></script>
99
<script src="common.js"></script>
1010
<link href="style.css" rel="stylesheet" type="text/css" media="screen" />
@@ -26,6 +26,7 @@ <h3>FirebaseUI Demo</h3>
2626
<div id="name"></div>
2727
<div id="email"></div>
2828
<div id="phone"></div>
29+
<div id="is-new-user"></div>
2930
<div class="clearfix"></div>
3031
</div>
3132
<p>

javascript/widgets/authui.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -869,7 +869,7 @@ firebaseui.auth.AuthUI.prototype.showOneTapSignIn = function(handler) {
869869
* Sign in using an email and password.
870870
* @param {string} email The email to sign in with.
871871
* @param {string} password The password to sign in with.
872-
* @return {!firebase.Promise<!firebase.User>}
872+
* @return {!firebase.Promise<!firebase.auth.UserCredential>}
873873
*/
874874
firebaseui.auth.AuthUI.prototype.startSignInWithEmailAndPassword =
875875
function(email, password) {
@@ -881,8 +881,8 @@ firebaseui.auth.AuthUI.prototype.startSignInWithEmailAndPassword =
881881
// always fail when upgrading an anonymous user. For the non-anonymous upgrade
882882
// flow, the same credential will be used to complete sign in on the
883883
// external Auth instance.
884-
return /** @type {!firebase.Promise<!firebase.User>} */ (
885-
this.getAuth().signInWithEmailAndPassword(email, password)
884+
return /** @type {!firebase.Promise<!firebase.auth.UserCredential>} */ (
885+
this.getAuth().signInAndRetrieveDataWithEmailAndPassword(email, password)
886886
.then(function(result) {
887887
var cb = function(user) {
888888
if (user) {
@@ -1276,7 +1276,7 @@ firebaseui.auth.AuthUI.prototype.finishSignInAndRetrieveDataWithAuthResult =
12761276
* recover from an existing email error.
12771277
* @param {string} email The email to sign in with.
12781278
* @param {string} password The password to sign in with.
1279-
* @return {!firebase.Promise<!firebase.User>}
1279+
* @return {!firebase.Promise<!firebase.auth.UserCredential>}
12801280
*/
12811281
firebaseui.auth.AuthUI.prototype.signInWithExistingEmailAndPasswordForLinking =
12821282
function(email, password) {
@@ -1285,7 +1285,8 @@ firebaseui.auth.AuthUI.prototype.signInWithExistingEmailAndPasswordForLinking =
12851285
// Starts sign in with email/password on the internal Auth instance for
12861286
// linking purposes. This is needed to avoid triggering the onAuthStateChanged
12871287
// callbacks interrupting the linking flow.
1288-
return this.getAuth().signInWithEmailAndPassword(email, password);
1288+
return this.getAuth().signInAndRetrieveDataWithEmailAndPassword(
1289+
email, password);
12891290
};
12901291

12911292

javascript/widgets/authui_test.js

Lines changed: 62 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1339,16 +1339,25 @@ function testStartSignInWithEmailAndPassword_success() {
13391339
app.getAuth().install();
13401340
app.getExternalAuth().install();
13411341
asyncTestCase.waitForSignals(1);
1342+
var expectedUserCredential = {
1343+
'user': expectedUser,
1344+
'credential': null,
1345+
'operationType': 'signIn',
1346+
'additionalUserInfo': {'providerId': 'password', 'isNewUser': false}
1347+
};
13421348
app.startSignInWithEmailAndPassword('[email protected]', 'password')
1343-
.then(function(user) {
1344-
assertEquals(app.getAuth().currentUser, user);
1349+
.then(function(userCredential) {
1350+
assertObjectEquals(expectedUserCredential, userCredential);
13451351
asyncTestCase.signal();
13461352
});
1347-
app.getAuth().assertSignInWithEmailAndPassword(
1353+
app.getAuth().assertSignInAndRetrieveDataWithEmailAndPassword(
13481354
['[email protected]', 'password'],
13491355
function() {
13501356
app.getAuth().setUser(expectedUser);
1351-
return app.getAuth().currentUser;
1357+
// Make a copy of expected UserCredential to ensure
1358+
// expectedUserCredential which is used to be compared with later will
1359+
// not be modified.
1360+
return goog.object.clone(expectedUserCredential);
13521361
});
13531362
app.getAuth().process();
13541363
app.getExternalAuth().process();
@@ -1371,7 +1380,7 @@ function testStartSignInWithEmailAndPassword_error() {
13711380
assertEquals(expectedError, error);
13721381
asyncTestCase.signal();
13731382
});
1374-
app.getAuth().assertSignInWithEmailAndPassword(
1383+
app.getAuth().assertSignInAndRetrieveDataWithEmailAndPassword(
13751384
['[email protected]', 'password'],
13761385
null,
13771386
expectedError);
@@ -1418,11 +1427,16 @@ function testStartSignInWithEmailAndPassword_upgradeAnon_isAnonymous_success() {
14181427
});
14191428
// Simulate anonymous user logged in on external instance.
14201429
testAuth.setUser(anonymousUser);
1421-
app.getAuth().assertSignInWithEmailAndPassword(
1430+
app.getAuth().assertSignInAndRetrieveDataWithEmailAndPassword(
14221431
['[email protected]', 'password'],
14231432
function() {
14241433
app.getAuth().setUser(expectedUser);
1425-
return app.getAuth().currentUser;
1434+
return {
1435+
'user': expectedUser,
1436+
'credential': null,
1437+
'operationType': 'signIn',
1438+
'additionalUserInfo': {'providerId': 'password', 'isNewUser': false}
1439+
};
14261440
});
14271441
app.getAuth().process().then(function() {
14281442
// Trigger initial onAuthStateChanged listener.
@@ -1466,7 +1480,7 @@ function testStartSignInWithEmailAndPassword_upgradeAnon_isAnon_error() {
14661480
asyncTestCase.signal();
14671481
});
14681482
// Simulate wrong password error on sign-in.
1469-
app.getAuth().assertSignInWithEmailAndPassword(
1483+
app.getAuth().assertSignInAndRetrieveDataWithEmailAndPassword(
14701484
['[email protected]', 'password'],
14711485
null,
14721486
expectedError);
@@ -1486,16 +1500,25 @@ function testStartSignInWithEmailAndPassword_upgradeAnon_nonAnon_success() {
14861500
asyncTestCase.waitForSignals(1);
14871501
// Simulate non-anonymous user logged in on external instance.
14881502
testAuth.setUser(expectedUser);
1503+
var expectedUserCredential = {
1504+
'user': expectedUser,
1505+
'credential': null,
1506+
'operationType': 'signIn',
1507+
'additionalUserInfo': {'providerId': 'password', 'isNewUser': false}
1508+
};
14891509
app.startSignInWithEmailAndPassword('[email protected]', 'password')
1490-
.then(function(user) {
1491-
assertEquals(app.getAuth().currentUser, user);
1510+
.then(function(userCredential) {
1511+
assertObjectEquals(expectedUserCredential, userCredential);
14921512
asyncTestCase.signal();
14931513
});
1494-
app.getAuth().assertSignInWithEmailAndPassword(
1514+
app.getAuth().assertSignInAndRetrieveDataWithEmailAndPassword(
14951515
['[email protected]', 'password'],
14961516
function() {
14971517
app.getAuth().setUser(expectedUser);
1498-
return app.getAuth().currentUser;
1518+
// Make a copy of expected UserCredential to ensure
1519+
// expectedUserCredential which is used to be compared with later will
1520+
// not be modified.
1521+
return goog.object.clone(expectedUserCredential);
14991522
});
15001523
app.getAuth().process().then(function() {
15011524
// Trigger initial onAuthStateChanged listener.
@@ -1517,16 +1540,25 @@ function testStartSignInWithEmailAndPassword_upgradeAnonymous_noUser_success() {
15171540
asyncTestCase.waitForSignals(1);
15181541
// Simulate no user logged in on external instance.
15191542
testAuth.setUser(null);
1543+
var expectedUserCredential = {
1544+
'user': expectedUser,
1545+
'credential': null,
1546+
'operationType': 'signIn',
1547+
'additionalUserInfo': {'providerId': 'password', 'isNewUser': false}
1548+
};
15201549
app.startSignInWithEmailAndPassword('[email protected]', 'password')
1521-
.then(function(user) {
1522-
assertEquals(app.getAuth().currentUser, user);
1550+
.then(function(userCredential) {
1551+
assertObjectEquals(expectedUserCredential, userCredential);
15231552
asyncTestCase.signal();
15241553
});
1525-
app.getAuth().assertSignInWithEmailAndPassword(
1554+
app.getAuth().assertSignInAndRetrieveDataWithEmailAndPassword(
15261555
['[email protected]', 'password'],
15271556
function() {
15281557
app.getAuth().setUser(expectedUser);
1529-
return app.getAuth().currentUser;
1558+
// Make a copy of expected UserCredential to ensure
1559+
// expectedUserCredential which is used to be compared with later will
1560+
// not be modified.
1561+
return goog.object.clone(expectedUserCredential);
15301562
});
15311563
app.getAuth().process().then(function() {
15321564
// Trigger initial onAuthStateChanged listener.
@@ -3768,17 +3800,26 @@ function testSignInWithExistingEmailAndPasswordForLinking_success() {
37683800
app.getAuth().install();
37693801
app.getExternalAuth().install();
37703802
asyncTestCase.waitForSignals(1);
3803+
var expectedUserCredential = {
3804+
'user': expectedUser,
3805+
'credential': null,
3806+
'operationType': 'signIn',
3807+
'additionalUserInfo': {'providerId': 'password', 'isNewUser': false}
3808+
};
37713809
app.signInWithExistingEmailAndPasswordForLinking(
37723810
'[email protected]', 'password')
3773-
.then(function(user) {
3774-
assertEquals(app.getAuth().currentUser, user);
3811+
.then(function(userCredential) {
3812+
assertObjectEquals(expectedUserCredential, userCredential);
37753813
asyncTestCase.signal();
37763814
});
3777-
app.getAuth().assertSignInWithEmailAndPassword(
3815+
app.getAuth().assertSignInAndRetrieveDataWithEmailAndPassword(
37783816
['[email protected]', 'password'],
37793817
function() {
37803818
app.getAuth().setUser(expectedUser);
3781-
return app.getAuth().currentUser;
3819+
// Make a copy of expected UserCredential to ensure
3820+
// expectedUserCredential which is used to be compared with later will
3821+
// not be modified.
3822+
return goog.object.clone(expectedUserCredential);
37823823
});
37833824
app.getAuth().process();
37843825
app.getExternalAuth().process();
@@ -3802,7 +3843,7 @@ function testSignInWithExistingEmailAndPasswordForLinking_error() {
38023843
assertEquals(expectedError, error);
38033844
asyncTestCase.signal();
38043845
});
3805-
app.getAuth().assertSignInWithEmailAndPassword(
3846+
app.getAuth().assertSignInAndRetrieveDataWithEmailAndPassword(
38063847
['[email protected]', 'password'],
38073848
null,
38083849
expectedError);

0 commit comments

Comments
 (0)