Skip to content

Commit 1abb6ce

Browse files
authored
Add snippets for Handling the account-exists-with-different… (#367)
* Add v8 and v9 snippets for Handling the account-exists-with-different-credential error * Import auth functions * Add missing methods to param * Add missing methods to params for legacy snippets
1 parent a9160f6 commit 1abb6ce

File tree

3 files changed

+175
-0
lines changed

3 files changed

+175
-0
lines changed

auth-next/link-multiple-accounts.js

+58
Original file line numberDiff line numberDiff line change
@@ -182,3 +182,61 @@ function unlink(providerId) {
182182
});
183183
// [END auth_unlink_provider]
184184
}
185+
186+
function accountExistsPopup(auth, facebookProvider, goToApp, promptUserForPassword, promptUserForSignInMethod, getProviderForProviderId) {
187+
// [START account_exists_popup]
188+
const { signInWithPopup, signInWithEmailAndPassword, linkWithCredential } = require("firebase/auth");
189+
190+
// User tries to sign in with Facebook.
191+
signInWithPopup(auth, facebookProvider).catch((error) => {
192+
// User's email already exists.
193+
if (error.code === 'auth/account-exists-with-different-credential') {
194+
// The pending Facebook credential.
195+
const pendingCred = error.credential;
196+
// The provider account's email address.
197+
const email = error.customData.email;
198+
199+
// Present the user with a list of providers they might have
200+
// used to create the original account.
201+
// Then, ask the user to sign in with the existing provider.
202+
const method = promptUserForSignInMethod();
203+
204+
if (method === 'password') {
205+
// TODO: Ask the user for their password.
206+
// In real scenario, you should handle this asynchronously.
207+
const password = promptUserForPassword();
208+
signInWithEmailAndPassword(auth, email, password).then((result) => {
209+
return linkWithCredential(result.user, pendingCred);
210+
}).then(() => {
211+
// Facebook account successfully linked to the existing user.
212+
goToApp();
213+
});
214+
return;
215+
}
216+
217+
// All other cases are external providers.
218+
// Construct provider object for that provider.
219+
// TODO: Implement getProviderForProviderId.
220+
const provider = getProviderForProviderId(method);
221+
// At this point, you should let the user know that they already have an
222+
// account with a different provider, and validate they want to sign in
223+
// with the new provider.
224+
// Note: Browsers usually block popups triggered asynchronously, so in
225+
// real app, you should ask the user to click on a "Continue" button
226+
// that will trigger signInWithPopup().
227+
signInWithPopup(auth, provider).then((result) => {
228+
// Note: Identity Platform doesn't control the provider's sign-in
229+
// flow, so it's possible for the user to sign in with an account
230+
// with a different email from the first one.
231+
232+
// Link the Facebook credential. We have access to the pending
233+
// credential, so we can directly call the link method.
234+
linkWithCredential(result.user, pendingCred).then((userCred) => {
235+
// Success.
236+
goToApp();
237+
});
238+
});
239+
}
240+
});
241+
// [END account_exists_popup]
242+
}

auth/link-multiple-accounts.js

+56
Original file line numberDiff line numberDiff line change
@@ -166,3 +166,59 @@ function unlink(providerId) {
166166
});
167167
// [END auth_unlink_provider]
168168
}
169+
170+
function accountExistsPopup(facebookProvider, goToApp, promptUserForPassword, promptUserForSignInMethod, getProviderForProviderId) {
171+
// [START account_exists_popup]
172+
// User tries to sign in with Facebook.
173+
auth.signInWithPopup(facebookProvider).catch((error) => {
174+
// User's email already exists.
175+
if (error.code === 'auth/account-exists-with-different-credential') {
176+
// The pending Facebook credential.
177+
const pendingCred = error.credential;
178+
// The provider account's email address.
179+
const email = error.email;
180+
181+
// Present the user with a list of providers they might have
182+
// used to create the original account.
183+
// Then, ask the user to sign in with the existing provider.
184+
const method = promptUserForSignInMethod();
185+
186+
if (method === 'password') {
187+
// TODO: Ask the user for their password.
188+
// In real scenario, you should handle this asynchronously.
189+
const password = promptUserForPassword();
190+
auth.signInWithEmailAndPassword(email, password).then((result) => {
191+
return result.user.linkWithCredential(pendingCred);
192+
}).then(() => {
193+
// Facebook account successfully linked to the existing user.
194+
goToApp();
195+
});
196+
return;
197+
}
198+
199+
// All other cases are external providers.
200+
// Construct provider object for that provider.
201+
// TODO: Implement getProviderForProviderId.
202+
const provider = getProviderForProviderId(method);
203+
// At this point, you should let the user know that they already have an
204+
// account with a different provider, and validate they want to sign in
205+
// with the new provider.
206+
// Note: Browsers usually block popups triggered asynchronously, so in
207+
// real app, you should ask the user to click on a "Continue" button
208+
// that will trigger signInWithPopup().
209+
auth.signInWithPopup(provider).then((result) => {
210+
// Note: Identity Platform doesn't control the provider's sign-in
211+
// flow, so it's possible for the user to sign in with an account
212+
// with a different email from the first one.
213+
214+
// Link the Facebook credential. We have access to the pending
215+
// credential, so we can directly call the link method.
216+
result.user.linkWithCredential(pendingCred).then((userCred) => {
217+
// Success.
218+
goToApp();
219+
});
220+
});
221+
}
222+
});
223+
// [END account_exists_popup]
224+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// This snippet file was generated by processing the source file:
2+
// ./auth-next/link-multiple-accounts.js
3+
//
4+
// To update the snippets in this file, edit the source and then run
5+
// 'npm run snippets'.
6+
7+
// [START account_exists_popup_modular]
8+
import { signInWithPopup, signInWithEmailAndPassword, linkWithCredential } from "firebase/auth";
9+
10+
// User tries to sign in with Facebook.
11+
signInWithPopup(auth, facebookProvider).catch((error) => {
12+
// User's email already exists.
13+
if (error.code === 'auth/account-exists-with-different-credential') {
14+
// The pending Facebook credential.
15+
const pendingCred = error.credential;
16+
// The provider account's email address.
17+
const email = error.customData.email;
18+
19+
// Present the user with a list of providers they might have
20+
// used to create the original account.
21+
// Then, ask the user to sign in with the existing provider.
22+
const method = promptUserForSignInMethod();
23+
24+
if (method === 'password') {
25+
// TODO: Ask the user for their password.
26+
// In real scenario, you should handle this asynchronously.
27+
const password = promptUserForPassword();
28+
signInWithEmailAndPassword(auth, email, password).then((result) => {
29+
return linkWithCredential(result.user, pendingCred);
30+
}).then(() => {
31+
// Facebook account successfully linked to the existing user.
32+
goToApp();
33+
});
34+
return;
35+
}
36+
37+
// All other cases are external providers.
38+
// Construct provider object for that provider.
39+
// TODO: Implement getProviderForProviderId.
40+
const provider = getProviderForProviderId(method);
41+
// At this point, you should let the user know that they already have an
42+
// account with a different provider, and validate they want to sign in
43+
// with the new provider.
44+
// Note: Browsers usually block popups triggered asynchronously, so in
45+
// real app, you should ask the user to click on a "Continue" button
46+
// that will trigger signInWithPopup().
47+
signInWithPopup(auth, provider).then((result) => {
48+
// Note: Identity Platform doesn't control the provider's sign-in
49+
// flow, so it's possible for the user to sign in with an account
50+
// with a different email from the first one.
51+
52+
// Link the Facebook credential. We have access to the pending
53+
// credential, so we can directly call the link method.
54+
linkWithCredential(result.user, pendingCred).then((userCred) => {
55+
// Success.
56+
goToApp();
57+
});
58+
});
59+
}
60+
});
61+
// [END account_exists_popup_modular]

0 commit comments

Comments
 (0)