Skip to content

Commit bb41bf1

Browse files
committed
-
1 parent f0caec0 commit bb41bf1

File tree

1 file changed

+201
-6
lines changed

1 file changed

+201
-6
lines changed

MIGRATION.md

Lines changed: 201 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -169,14 +169,209 @@ The following table maps v6 configuration options to their v7 equivalents:
169169
| v6 Option | Migration Guide |
170170
|----------|------------------|
171171
| `autoUpgradeAnonymousUsers` | **Use the `autoUpgradeAnonymousUsers` behavior.**<br/><br/>Import `autoUpgradeAnonymousUsers` from `@invertase/firebaseui-core` and add it to your behaviors array:<br/>`behaviors: [autoUpgradeAnonymousUsers({ async onUpgrade(ui, oldUserId, credential) { /* handle merge */ } })]`<br/><br/>The `onUpgrade` callback replaces the `signInFailure` callback for handling merge conflicts. |
172-
| `callbacks` | **Use component props instead.**<br/><br/>v6 callbacks like `signInSuccessWithAuthResult`, `signInFailure`, etc. are replaced by component event handlers:<br/>- `onSignIn={(user) => { ... }}` on screen components<br/>- `onSignUp={(user) => { ... }}` on screen components<br/>- `onForgotPasswordClick={() => { ... }}` on form components<br/><br/>These are passed directly to the components you use, giving you more control over the flow. |
172+
| `callbacks` | **Use component props/events instead.**<br/><br/>v6 callbacks like `signInSuccessWithAuthResult`, `signInFailure`, etc. are replaced by component event handlers:<br/><br/>**React:** `onSignIn={(user) => { ... }}`, `onSignUp={(user) => { ... }}`, `onForgotPasswordClick={() => { ... }}`<br/><br/>**Angular:** `(signIn)="onSignIn($event)"`, `(signUp)="onSignUp($event)"`, `(forgotPassword)="onForgotPassword()"`<br/><br/>These are passed directly to the components you use, giving you more control over the flow. |
173173
| `credentialHelper` | **Use the `oneTapSignIn` behavior.**<br/><br/>The credential helper (Account Chooser) from v6 is replaced by Google One Tap in v7. Import `oneTapSignIn` from `@invertase/firebaseui-core` and add it to your behaviors array:<br/>`behaviors: [oneTapSignIn({ clientId: '...', autoSelect: false, cancelOnTapOutside: false })]`<br/><br/>**Note:** This requires Google Sign In to be enabled in Firebase Console. Get the `clientId` from "Web SDK configuration" settings. See [Google One Tap documentation](https://developers.google.com/identity/gsi/web/reference/js-reference) for all configuration options. |
174-
| `queryParameterForSignInSuccessUrl` | **Handle in your routing logic.**<br/><br/>v7 doesn't have built-in URL parameter handling. Instead, handle redirects in your `onSignIn` callback by reading URL params:<br/>`const urlParams = new URLSearchParams(window.location.search);`<br/>`const redirectUrl = urlParams.get('signInSuccessUrl') || '/dashboard';`<br/>`window.location.href = redirectUrl;` |
175-
| `queryParameterForWidgetMode` | **Not applicable.**<br/><br/>v7 doesn't use widget modes. Instead, you explicitly render the components you need (e.g., `<SignInAuthScreen />`, `<SignUpAuthScreen />`, etc.) in your application. |
174+
| `queryParameterForSignInSuccessUrl` | **Handle in your routing logic.**<br/><br/>v7 doesn't have built-in URL parameter handling. Instead, handle redirects in your `onSignIn` callback by reading URL params:<br/><br/>**React/Angular:** `const urlParams = new URLSearchParams(window.location.search);`<br/>`const redirectUrl = urlParams.get('signInSuccessUrl') || '/dashboard';`<br/>`window.location.href = redirectUrl;`<br/><br/>**Angular (with Router):** Use `ActivatedRoute` to read query params and `Router` to navigate. |
175+
| `queryParameterForWidgetMode` | **Not applicable.**<br/><br/>v7 doesn't use widget modes. Instead, you explicitly render the components you need:<br/><br/>**React:** `<SignInAuthScreen />`, `<SignUpAuthScreen />`<br/><br/>**Angular:** `<fui-sign-in-auth-screen>`, `<fui-sign-up-auth-screen>` |
176176
| `signInFlow` | **Use provider strategy behaviors.**<br/><br/>Replace `signInFlow: 'redirect'` with:<br/>`import { providerRedirectStrategy } from '@invertase/firebaseui-core'`<br/>`behaviors: [providerRedirectStrategy()]`<br/><br/>Replace `signInFlow: 'popup'` with:<br/>`import { providerPopupStrategy } from '@invertase/firebaseui-core'`<br/>`behaviors: [providerPopupStrategy()]`<br/><br/>**Note:** `popup` is the default strategy in v7. |
177-
| `immediateFederatedRedirect` | **Control via component rendering.**<br/><br/>v7 doesn't have this option. Instead, you control whether to show OAuth buttons or redirect immediately by conditionally rendering components:<br/>`{singleProvider ? <Navigate to="/oauth-redirect" /> : <OAuthScreen onSignIn={handleSignIn} />}` |
178-
| `signInOptions` | **Use OAuth button components directly.**<br/><br/>v6's `signInOptions` array is replaced by explicitly rendering the OAuth provider buttons you want. Import buttons like `GoogleSignInButton`, `FacebookSignInButton`, `AppleSignInButton` from `@invertase/firebaseui-react` and render them inside `<OAuthScreen>`. The order you place the buttons determines their display order. |
179-
| `signInSuccessUrl` | **Handle in `onSignIn` callback.**<br/><br/>Instead of a configuration option, handle redirects in your component's `onSignIn` callback:<br/>`<SignInAuthScreen onSignIn={(user) => { window.location.href = '/dashboard'; }} />`<br/><br/>*Required in v6 when `signInSuccessWithAuthResult` callback is not used or returns `true`. |
177+
| `immediateFederatedRedirect` | **Control via component rendering.**<br/><br/>v7 doesn't have this option. Instead, you control whether to show OAuth buttons or redirect immediately by conditionally rendering components:<br/><br/>**React:** `{singleProvider ? <Navigate to="/oauth-redirect" /> : <OAuthScreen onSignIn={handleSignIn} />}`<br/><br/>**Angular:** Use `*ngIf` or `@if` to conditionally render `<fui-oauth-screen>` or use `Router` to navigate directly. |
178+
| `signInOptions` | **Use OAuth button components directly.**<br/><br/>v6's `signInOptions` array is replaced by explicitly rendering the OAuth provider buttons you want:<br/><br/>**React:** Import `GoogleSignInButton`, `FacebookSignInButton`, `AppleSignInButton` from `@invertase/firebaseui-react` and render them inside `<OAuthScreen>`.<br/><br/>**Angular:** Import `GoogleSignInButtonComponent`, `FacebookSignInButtonComponent`, `AppleSignInButtonComponent` from `@invertase/firebaseui-angular` and use selectors `<fui-google-sign-in-button>`, `<fui-facebook-sign-in-button>`, `<fui-apple-sign-in-button>` inside `<fui-oauth-screen>`.<br/><br/>The order you place the buttons determines their display order. |
179+
| `signInSuccessUrl` | **Handle in `onSignIn` callback.**<br/><br/>Instead of a configuration option, handle redirects in your component's `onSignIn` callback:<br/><br/>**React:** `<SignInAuthScreen onSignIn={(user) => { window.location.href = '/dashboard'; }} />`<br/><br/>**Angular:** `<fui-sign-in-auth-screen (signIn)="onSignIn($event)" />` with `onSignIn(user: User) { this.router.navigate(['/dashboard']); }`<br/><br/>*Required in v6 when `signInSuccessWithAuthResult` callback is not used or returns `true`. |
180180
| `tosUrl` | **Pass via `policies` prop.**<br/><br/>**React:** Pass `policies={{ termsOfServiceUrl: 'https://example.com/tos', privacyPolicyUrl: 'https://example.com/privacy' }}` to `<FirebaseUIProvider>`.<br/><br/>**Angular:** Use `provideFirebaseUIPolicies(() => ({ termsOfServiceUrl: '...', privacyPolicyUrl: '...' }))`.<br/><br/>The policies are automatically rendered in auth forms and screens. |
181181
| `privacyPolicyUrl` | **Pass via `policies` prop.**<br/><br/>See `tosUrl` above - both URLs are passed together in the `policies` object. |
182182
| `adminRestrictedOperation` | **Handle in your UI logic.**<br/><br/>v7 doesn't have built-in support for this GCIP-specific feature. You'll need to:<br/>(1) Check if sign-up is disabled in your Firebase project settings<br/>(2) Handle the `auth/admin-restricted-operation` error in your error handling<br/>(3) Display appropriate messaging to users when sign-up attempts are blocked<br/><br/>You can check for this error in your `onSignUp` or form error handlers and display custom UI accordingly. |
183+
184+
### Additional Configuration
185+
186+
#### Configure Phone Provider
187+
188+
In v6, phone authentication country code configuration was handled via the `signInOptions` configuration. In v7, this is controlled by the `countryCodes` behavior.
189+
190+
**v6:**
191+
```javascript
192+
signInOptions: [
193+
{
194+
provider: firebase.auth.PhoneAuthProvider.PROVIDER_ID,
195+
defaultCountry: 'GB',
196+
whitelistedCountries: ['GB', 'US', 'FR']
197+
}
198+
]
199+
```
200+
201+
**v7:**
202+
Use the `countryCodes` behavior to configure allowed countries and default country:
203+
204+
```ts
205+
import { countryCodes } from '@invertase/firebaseui-core';
206+
207+
const ui = initializeUI({
208+
app,
209+
behaviors: [
210+
countryCodes({
211+
allowedCountries: ['GB', 'US', 'FR'], // only allow Great Britain, USA and France
212+
defaultCountry: 'GB', // GB is default
213+
}),
214+
],
215+
});
216+
```
217+
218+
The `countryCodes` behavior affects all phone authentication flows, including regular phone sign-in and multi-factor authentication (MFA) enrollment. The `CountrySelector` component automatically uses these settings to filter and display available countries.
219+
220+
#### Sign In Flows
221+
222+
In v6, you configured the sign-in flow (popup vs redirect) via the `signInFlow` configuration option. In v7, this is controlled by provider strategy behaviors.
223+
224+
**v6:**
225+
```javascript
226+
var uiConfig = {
227+
signInFlow: 'popup', // or 'redirect'
228+
// ...
229+
};
230+
```
231+
232+
**v7:**
233+
Use the `providerPopupStrategy` (default) or `providerRedirectStrategy` behaviors:
234+
235+
```ts
236+
import { providerPopupStrategy, providerRedirectStrategy } from '@invertase/firebaseui-core';
237+
238+
// For popup flow (default)
239+
const ui = initializeUI({
240+
app,
241+
behaviors: [providerPopupStrategy()],
242+
});
243+
244+
// For redirect flow
245+
const ui = initializeUI({
246+
app,
247+
behaviors: [providerRedirectStrategy()],
248+
});
249+
```
250+
251+
**Note:** The popup strategy is the default in v7. If you don't specify a strategy, popup will be used. The strategy applies to all OAuth providers (Google, Facebook, Apple, etc.).
252+
253+
#### Multi-tenancy Support
254+
255+
v7 supports multi-tenancy by allowing you to pass a custom `Auth` instance with a `tenantId` configured to `initializeUI`.
256+
257+
**v6:**
258+
```javascript
259+
var tenantAuth = firebase.auth(app).tenantId = 'tenant-id';
260+
var ui = new firebaseui.auth.AuthUI(tenantAuth);
261+
```
262+
263+
**v7:**
264+
265+
**React:**
266+
```tsx
267+
import { getAuth } from 'firebase/auth';
268+
import { initializeUI } from '@invertase/firebaseui-core';
269+
270+
const auth = getAuth(app);
271+
auth.tenantId = 'tenant-id';
272+
273+
const ui = initializeUI({
274+
app,
275+
auth, // Pass the auth instance with tenantId
276+
});
277+
```
278+
279+
**Angular:**
280+
```ts
281+
import { getAuth } from 'firebase/auth';
282+
import { initializeUI } from '@invertase/firebaseui-core';
283+
284+
export const appConfig: ApplicationConfig = {
285+
providers: [
286+
provideFirebaseApp(() => initializeApp({ ... })),
287+
provideAuth(() => {
288+
const auth = getAuth();
289+
auth.tenantId = 'tenant-id';
290+
return auth;
291+
}),
292+
provideFirebaseUI((apps) => {
293+
const auth = getAuth(apps[0]);
294+
auth.tenantId = 'tenant-id';
295+
return initializeUI({
296+
app: apps[0],
297+
auth,
298+
});
299+
}),
300+
],
301+
};
302+
```
303+
304+
#### Enabling Anonymous User Upgrade
305+
306+
In v6, anonymous user upgrade was configured via the `autoUpgradeAnonymousUsers` option. In v7, this is handled by the `autoUpgradeAnonymousUsers` behavior.
307+
308+
**v6:**
309+
```javascript
310+
var uiConfig = {
311+
autoUpgradeAnonymousUsers: true,
312+
callbacks: {
313+
signInFailure: function(error) {
314+
// Handle merge conflicts
315+
}
316+
}
317+
};
318+
```
319+
320+
**v7:**
321+
Use the `autoUpgradeAnonymousUsers` behavior:
322+
323+
```ts
324+
import { autoUpgradeAnonymousUsers } from '@invertase/firebaseui-core';
325+
326+
const ui = initializeUI({
327+
app,
328+
behaviors: [
329+
autoUpgradeAnonymousUsers({
330+
async onUpgrade(ui, oldUserId, credential) {
331+
// Handle account merge logic
332+
// e.g., migrate data from oldUserId to new user
333+
console.log(`Upgrading anonymous user ${oldUserId} to ${credential.user.uid}`);
334+
},
335+
}),
336+
],
337+
});
338+
```
339+
340+
The behavior automatically upgrades anonymous users when they sign in with any credential (email/password, OAuth, phone, etc.). The `onUpgrade` callback is optional and allows you to perform custom logic during the upgrade, such as migrating user data.
341+
342+
#### Handling Anonymous User Upgrade Merge Conflicts
343+
344+
In v6, merge conflicts (when an account already exists with the same credential) were handled via the `signInFailure` callback. In v7, the upgrade process handles this differently.
345+
346+
**How it works in v7:**
347+
348+
When an anonymous user attempts to sign in with a credential that's already associated with an existing account, Firebase Auth will automatically link the anonymous account to the existing account. The upgrade process:
349+
350+
1. **Stores the anonymous user ID** in `localStorage` before redirect flows (for OAuth redirects)
351+
2. **Automatically links** the anonymous account to the existing account
352+
3. **Calls the `onUpgrade` callback** (if provided) with both the old anonymous user ID and the new credential
353+
4. **Cleans up** the stored anonymous user ID from `localStorage`
354+
355+
**Example:**
356+
```ts
357+
const ui = initializeUI({
358+
app,
359+
behaviors: [
360+
autoUpgradeAnonymousUsers({
361+
async onUpgrade(ui, oldUserId, credential) {
362+
// oldUserId is the anonymous user's ID
363+
// credential.user.uid is the existing account's ID after linking
364+
365+
// Migrate any data from the anonymous account
366+
await migrateUserData(oldUserId, credential.user.uid);
367+
368+
// The anonymous account is now linked to the existing account
369+
// The user is signed in with their existing account
370+
},
371+
}),
372+
],
373+
});
374+
```
375+
376+
**Note:** If a merge conflict occurs and the linking fails (e.g., due to account linking restrictions), Firebase Auth will throw an error that you can handle in your error handling logic. The `onUpgrade` callback will only be called if the upgrade is successful.
377+

0 commit comments

Comments
 (0)