From d781c67b528afe99fcdb7c7056104772463fa3ec Mon Sep 17 00:00:00 2001 From: Jonas Kaas Date: Fri, 29 Sep 2023 17:51:19 +0200 Subject: [PATCH 1/9] Fix comment for signup (#356) --- auth-next/email.js | 2 +- snippets/auth-next/email/auth_signup_password.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/auth-next/email.js b/auth-next/email.js index b00551c8..26391f81 100644 --- a/auth-next/email.js +++ b/auth-next/email.js @@ -32,7 +32,7 @@ function signUpWithEmailPassword() { const auth = getAuth(); createUserWithEmailAndPassword(auth, email, password) .then((userCredential) => { - // Signed in + // Signed up const user = userCredential.user; // ... }) diff --git a/snippets/auth-next/email/auth_signup_password.js b/snippets/auth-next/email/auth_signup_password.js index 00aa9bd5..936b64ce 100644 --- a/snippets/auth-next/email/auth_signup_password.js +++ b/snippets/auth-next/email/auth_signup_password.js @@ -10,7 +10,7 @@ import { getAuth, createUserWithEmailAndPassword } from "firebase/auth"; const auth = getAuth(); createUserWithEmailAndPassword(auth, email, password) .then((userCredential) => { - // Signed in + // Signed up const user = userCredential.user; // ... }) From 1f9e7978ed8f6805fad12b32f34b6216ab4556cb Mon Sep 17 00:00:00 2001 From: Morgan Chen Date: Thu, 9 Nov 2023 09:50:47 -0800 Subject: [PATCH 2/9] fix broken array-in snippets (#360) * fix broken array-in snippets * npm run snippets * revert array contians anay changes --- firestore-next/test.firestore.js | 2 +- firestore/test.firestore.js | 2 +- snippets/firestore-next/test-firestore/in_filter_with_array.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/firestore-next/test.firestore.js b/firestore-next/test.firestore.js index c961af9d..969c1654 100644 --- a/firestore-next/test.firestore.js +++ b/firestore-next/test.firestore.js @@ -920,7 +920,7 @@ describe("firestore", () => { // [START in_filter_with_array] const { query, where } = require("firebase/firestore"); - const q = query(citiesRef, where('regions', 'in', [['west_coast', 'east_coast']])); + const q = query(citiesRef, where('regions', 'in', [['west_coast'], ['east_coast']])); // [END in_filter_with_array] } }); diff --git a/firestore/test.firestore.js b/firestore/test.firestore.js index ec89172e..20032d36 100644 --- a/firestore/test.firestore.js +++ b/firestore/test.firestore.js @@ -893,7 +893,7 @@ describe("firestore", () => { // [START in_filter_with_array] citiesRef.where('regions', 'in', - [['west_coast', 'east_coast']]); + [['west_coast'], ['east_coast']]); // [END in_filter_with_array] }); diff --git a/snippets/firestore-next/test-firestore/in_filter_with_array.js b/snippets/firestore-next/test-firestore/in_filter_with_array.js index ebe6f18b..190e9dfe 100644 --- a/snippets/firestore-next/test-firestore/in_filter_with_array.js +++ b/snippets/firestore-next/test-firestore/in_filter_with_array.js @@ -7,5 +7,5 @@ // [START in_filter_with_array_modular] import { query, where } from "firebase/firestore"; -const q = query(citiesRef, where('regions', 'in', [['west_coast', 'east_coast']])); +const q = query(citiesRef, where('regions', 'in', [['west_coast'], ['east_coast']])); // [END in_filter_with_array_modular] \ No newline at end of file From e74e8fd9591f70007a44c58580ff0f1fcd1c7959 Mon Sep 17 00:00:00 2001 From: Kevin Sanders Date: Thu, 9 Nov 2023 21:07:49 -0500 Subject: [PATCH 3/9] Typo Fix (#361) --- auth-next/custom-email-handler.js | 4 ++-- .../custom-email-handler/auth_handle_mgmt_query_params.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/auth-next/custom-email-handler.js b/auth-next/custom-email-handler.js index 728baff8..5fcc1f71 100644 --- a/auth-next/custom-email-handler.js +++ b/auth-next/custom-email-handler.js @@ -28,8 +28,8 @@ function handleUserManagementQueryParams() { // Configure the Firebase SDK. // This is the minimum configuration required for the API to be used. const config = { - 'apiKey': "YOU_API_KEY" // Copy this key from the web initialization - // snippet found in the Firebase console. + 'apiKey': "YOUR_API_KEY" // Copy this key from the web initialization + // snippet found in the Firebase console. }; const app = initializeApp(config); const auth = getAuth(app); diff --git a/snippets/auth-next/custom-email-handler/auth_handle_mgmt_query_params.js b/snippets/auth-next/custom-email-handler/auth_handle_mgmt_query_params.js index 6dec3399..d0a22696 100644 --- a/snippets/auth-next/custom-email-handler/auth_handle_mgmt_query_params.js +++ b/snippets/auth-next/custom-email-handler/auth_handle_mgmt_query_params.js @@ -23,8 +23,8 @@ document.addEventListener('DOMContentLoaded', () => { // Configure the Firebase SDK. // This is the minimum configuration required for the API to be used. const config = { - 'apiKey': "YOU_API_KEY" // Copy this key from the web initialization - // snippet found in the Firebase console. + 'apiKey': "YOUR_API_KEY" // Copy this key from the web initialization + // snippet found in the Firebase console. }; const app = initializeApp(config); const auth = getAuth(app); From a9160f62f8ebff02285779974620ad3ff260f5ac Mon Sep 17 00:00:00 2001 From: James Daniels Date: Wed, 13 Mar 2024 16:22:44 -0400 Subject: [PATCH 4/9] FirebaseServerApp (#366) * First. * already snippets for that * cleanup * auth_svc_admin * Auth, not auth-next * Express stub should not be in snippet * Move import into snippet * Update firebaseserverapp.js --- auth/package.json | 1 + auth/service-worker-sessions.js | 43 +++++++++++++++++++++ firebaseserverapp-next/firebaseserverapp.js | 27 +++++++++++++ firebaseserverapp-next/package.json | 12 ++++++ 4 files changed, 83 insertions(+) create mode 100644 firebaseserverapp-next/firebaseserverapp.js create mode 100644 firebaseserverapp-next/package.json diff --git a/auth/package.json b/auth/package.json index a6827027..b4b13f01 100644 --- a/auth/package.json +++ b/auth/package.json @@ -7,6 +7,7 @@ "license": "Apache 2.0", "dependencies": { "firebase": "^8.10.0", + "firebase-admin": "^12.0.0", "firebaseui": "^5.0.0" } } diff --git a/auth/service-worker-sessions.js b/auth/service-worker-sessions.js index babbf91e..05791463 100644 --- a/auth/service-worker-sessions.js +++ b/auth/service-worker-sessions.js @@ -162,3 +162,46 @@ function svcSignInEmail(email, password) { }); // [END auth_svc_sign_in_email] } + +function svcRedirectAdmin() { + const app = { use: (a) => {} }; + + // [START auth_svc_admin] + // Server side code. + const admin = require('firebase-admin'); + + // The Firebase Admin SDK is used here to verify the ID token. + admin.initializeApp(); + + function getIdToken(req) { + // Parse the injected ID token from the request header. + const authorizationHeader = req.headers.authorization || ''; + const components = authorizationHeader.split(' '); + return components.length > 1 ? components[1] : ''; + } + + function checkIfSignedIn(url) { + return (req, res, next) => { + if (req.url == url) { + const idToken = getIdToken(req); + // Verify the ID token using the Firebase Admin SDK. + // User already logged in. Redirect to profile page. + admin.auth().verifyIdToken(idToken).then((decodedClaims) => { + // User is authenticated, user claims can be retrieved from + // decodedClaims. + // In this sample code, authenticated users are always redirected to + // the profile page. + res.redirect('/profile'); + }).catch((error) => { + next(); + }); + } else { + next(); + } + }; + } + + // If a user is signed in, redirect to profile page. + app.use(checkIfSignedIn('/')); + // [END auth_svc_admin] +} diff --git a/firebaseserverapp-next/firebaseserverapp.js b/firebaseserverapp-next/firebaseserverapp.js new file mode 100644 index 00000000..d0ab338c --- /dev/null +++ b/firebaseserverapp-next/firebaseserverapp.js @@ -0,0 +1,27 @@ +// @ts-nocheck +// [START serverapp_auth] +import { initializeServerApp } from 'firebase/app'; +import { getAuth } from 'firebase/auth'; +import { headers } from 'next/headers'; +import { redirect } from 'next/navigation'; + +export default function MyServerComponent() { + + // Get relevant request headers (in Next.JS) + const authIdToken = headers().get('Authorization')?.split('Bearer ')[1]; + + // Initialize the FirebaseServerApp instance. + const serverApp = initializeServerApp(firebaseConfig, { authIdToken }); + + // Initialize Firebase Authentication using the FirebaseServerApp instance. + const auth = getAuth(serverApp); + + if (auth.currentUser) { + redirect('/profile'); + } + + // ... +} +// [END serverapp_auth] + +const firebaseConfig = {}; diff --git a/firebaseserverapp-next/package.json b/firebaseserverapp-next/package.json new file mode 100644 index 00000000..0836b0b2 --- /dev/null +++ b/firebaseserverapp-next/package.json @@ -0,0 +1,12 @@ +{ + "name": "firebaseserverapp-next", + "version": "1.0.0", + "scripts": { + "compile": "cp ../tsconfig.json.template ./tsconfig.json && tsc" + }, + "license": "Apache-2.0", + "dependencies": { + "firebase": "^10.0.0", + "next": "^14.1.3" + } +} From 1abb6ce1a784ae5552946dff5f1f5aab7dcbda30 Mon Sep 17 00:00:00 2001 From: "Nhien (Ricky) Lam" <62775270+NhienLam@users.noreply.github.com> Date: Fri, 12 Apr 2024 16:24:45 -0700 Subject: [PATCH 5/9] =?UTF-8?q?Add=20snippets=20for=20Handling=20the=20acc?= =?UTF-8?q?ount-exists-with-different=E2=80=A6=20(#367)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 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 --- auth-next/link-multiple-accounts.js | 58 ++++++++++++++++++ auth/link-multiple-accounts.js | 56 +++++++++++++++++ .../account_exists_popup.js | 61 +++++++++++++++++++ 3 files changed, 175 insertions(+) create mode 100644 snippets/auth-next/link-multiple-accounts/account_exists_popup.js diff --git a/auth-next/link-multiple-accounts.js b/auth-next/link-multiple-accounts.js index 34c0db58..1938aafc 100644 --- a/auth-next/link-multiple-accounts.js +++ b/auth-next/link-multiple-accounts.js @@ -182,3 +182,61 @@ function unlink(providerId) { }); // [END auth_unlink_provider] } + +function accountExistsPopup(auth, facebookProvider, goToApp, promptUserForPassword, promptUserForSignInMethod, getProviderForProviderId) { + // [START account_exists_popup] + const { signInWithPopup, signInWithEmailAndPassword, linkWithCredential } = require("firebase/auth"); + + // User tries to sign in with Facebook. + signInWithPopup(auth, facebookProvider).catch((error) => { + // User's email already exists. + if (error.code === 'auth/account-exists-with-different-credential') { + // The pending Facebook credential. + const pendingCred = error.credential; + // The provider account's email address. + const email = error.customData.email; + + // Present the user with a list of providers they might have + // used to create the original account. + // Then, ask the user to sign in with the existing provider. + const method = promptUserForSignInMethod(); + + if (method === 'password') { + // TODO: Ask the user for their password. + // In real scenario, you should handle this asynchronously. + const password = promptUserForPassword(); + signInWithEmailAndPassword(auth, email, password).then((result) => { + return linkWithCredential(result.user, pendingCred); + }).then(() => { + // Facebook account successfully linked to the existing user. + goToApp(); + }); + return; + } + + // All other cases are external providers. + // Construct provider object for that provider. + // TODO: Implement getProviderForProviderId. + const provider = getProviderForProviderId(method); + // At this point, you should let the user know that they already have an + // account with a different provider, and validate they want to sign in + // with the new provider. + // Note: Browsers usually block popups triggered asynchronously, so in + // real app, you should ask the user to click on a "Continue" button + // that will trigger signInWithPopup(). + signInWithPopup(auth, provider).then((result) => { + // Note: Identity Platform doesn't control the provider's sign-in + // flow, so it's possible for the user to sign in with an account + // with a different email from the first one. + + // Link the Facebook credential. We have access to the pending + // credential, so we can directly call the link method. + linkWithCredential(result.user, pendingCred).then((userCred) => { + // Success. + goToApp(); + }); + }); + } +}); +// [END account_exists_popup] +} diff --git a/auth/link-multiple-accounts.js b/auth/link-multiple-accounts.js index 30f5a2ec..8eed77b8 100644 --- a/auth/link-multiple-accounts.js +++ b/auth/link-multiple-accounts.js @@ -166,3 +166,59 @@ function unlink(providerId) { }); // [END auth_unlink_provider] } + +function accountExistsPopup(facebookProvider, goToApp, promptUserForPassword, promptUserForSignInMethod, getProviderForProviderId) { + // [START account_exists_popup] + // User tries to sign in with Facebook. + auth.signInWithPopup(facebookProvider).catch((error) => { + // User's email already exists. + if (error.code === 'auth/account-exists-with-different-credential') { + // The pending Facebook credential. + const pendingCred = error.credential; + // The provider account's email address. + const email = error.email; + + // Present the user with a list of providers they might have + // used to create the original account. + // Then, ask the user to sign in with the existing provider. + const method = promptUserForSignInMethod(); + + if (method === 'password') { + // TODO: Ask the user for their password. + // In real scenario, you should handle this asynchronously. + const password = promptUserForPassword(); + auth.signInWithEmailAndPassword(email, password).then((result) => { + return result.user.linkWithCredential(pendingCred); + }).then(() => { + // Facebook account successfully linked to the existing user. + goToApp(); + }); + return; + } + + // All other cases are external providers. + // Construct provider object for that provider. + // TODO: Implement getProviderForProviderId. + const provider = getProviderForProviderId(method); + // At this point, you should let the user know that they already have an + // account with a different provider, and validate they want to sign in + // with the new provider. + // Note: Browsers usually block popups triggered asynchronously, so in + // real app, you should ask the user to click on a "Continue" button + // that will trigger signInWithPopup(). + auth.signInWithPopup(provider).then((result) => { + // Note: Identity Platform doesn't control the provider's sign-in + // flow, so it's possible for the user to sign in with an account + // with a different email from the first one. + + // Link the Facebook credential. We have access to the pending + // credential, so we can directly call the link method. + result.user.linkWithCredential(pendingCred).then((userCred) => { + // Success. + goToApp(); + }); + }); + } +}); +// [END account_exists_popup] +} diff --git a/snippets/auth-next/link-multiple-accounts/account_exists_popup.js b/snippets/auth-next/link-multiple-accounts/account_exists_popup.js new file mode 100644 index 00000000..2c667882 --- /dev/null +++ b/snippets/auth-next/link-multiple-accounts/account_exists_popup.js @@ -0,0 +1,61 @@ +// This snippet file was generated by processing the source file: +// ./auth-next/link-multiple-accounts.js +// +// To update the snippets in this file, edit the source and then run +// 'npm run snippets'. + + // [START account_exists_popup_modular] + import { signInWithPopup, signInWithEmailAndPassword, linkWithCredential } from "firebase/auth"; + + // User tries to sign in with Facebook. + signInWithPopup(auth, facebookProvider).catch((error) => { + // User's email already exists. + if (error.code === 'auth/account-exists-with-different-credential') { + // The pending Facebook credential. + const pendingCred = error.credential; + // The provider account's email address. + const email = error.customData.email; + + // Present the user with a list of providers they might have + // used to create the original account. + // Then, ask the user to sign in with the existing provider. + const method = promptUserForSignInMethod(); + + if (method === 'password') { + // TODO: Ask the user for their password. + // In real scenario, you should handle this asynchronously. + const password = promptUserForPassword(); + signInWithEmailAndPassword(auth, email, password).then((result) => { + return linkWithCredential(result.user, pendingCred); + }).then(() => { + // Facebook account successfully linked to the existing user. + goToApp(); + }); + return; + } + + // All other cases are external providers. + // Construct provider object for that provider. + // TODO: Implement getProviderForProviderId. + const provider = getProviderForProviderId(method); + // At this point, you should let the user know that they already have an + // account with a different provider, and validate they want to sign in + // with the new provider. + // Note: Browsers usually block popups triggered asynchronously, so in + // real app, you should ask the user to click on a "Continue" button + // that will trigger signInWithPopup(). + signInWithPopup(auth, provider).then((result) => { + // Note: Identity Platform doesn't control the provider's sign-in + // flow, so it's possible for the user to sign in with an account + // with a different email from the first one. + + // Link the Facebook credential. We have access to the pending + // credential, so we can directly call the link method. + linkWithCredential(result.user, pendingCred).then((userCred) => { + // Success. + goToApp(); + }); + }); + } +}); +// [END account_exists_popup_modular] \ No newline at end of file From 2117c619ce49b08d582f282e7d2ec798f5105c3d Mon Sep 17 00:00:00 2001 From: spider-hand Date: Wed, 29 May 2024 01:05:44 +0900 Subject: [PATCH 6/9] chore: update outdated comments (#370) --- auth-next/email-link-auth.js | 10 ++++++---- .../auth-next/email-link-auth/email_link_complete.js | 10 ++++++---- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/auth-next/email-link-auth.js b/auth-next/email-link-auth.js index 59ea2115..4748e699 100644 --- a/auth-next/email-link-auth.js +++ b/auth-next/email-link-auth.js @@ -68,11 +68,13 @@ function emailLinkComplete() { .then((result) => { // Clear email from storage. window.localStorage.removeItem('emailForSignIn'); - // You can access the new user via result.user - // Additional user info profile not available via: - // result.additionalUserInfo.profile == null + // You can access the new user by importing getAdditionalUserInfo + // and calling it with result: + // getAdditionalUserInfo(result) + // You can access the user's profile via: + // getAdditionalUserInfo(result)?.profile // You can check if the user is new or existing: - // result.additionalUserInfo.isNewUser + // getAdditionalUserInfo(result)?.isNewUser }) .catch((error) => { // Some error occurred, you can inspect the code: error.code diff --git a/snippets/auth-next/email-link-auth/email_link_complete.js b/snippets/auth-next/email-link-auth/email_link_complete.js index b42b9af9..dbe1143d 100644 --- a/snippets/auth-next/email-link-auth/email_link_complete.js +++ b/snippets/auth-next/email-link-auth/email_link_complete.js @@ -26,11 +26,13 @@ if (isSignInWithEmailLink(auth, window.location.href)) { .then((result) => { // Clear email from storage. window.localStorage.removeItem('emailForSignIn'); - // You can access the new user via result.user - // Additional user info profile not available via: - // result.additionalUserInfo.profile == null + // You can access the new user by importing getAdditionalUserInfo + // and calling it with result: + // getAdditionalUserInfo(result) + // You can access the user's profile via: + // getAdditionalUserInfo(result)?.profile // You can check if the user is new or existing: - // result.additionalUserInfo.isNewUser + // getAdditionalUserInfo(result)?.isNewUser }) .catch((error) => { // Some error occurred, you can inspect the code: error.code From 56d70627e2dc275f01cd0e55699794bf40faca80 Mon Sep 17 00:00:00 2001 From: Daniel La Rocque Date: Tue, 8 Oct 2024 15:17:01 -0400 Subject: [PATCH 7/9] Upgrade versions in FCM service worker (#382) * Upgrade versions in FCM service worker * Add comment telling users to use latest --- messaging/service-worker.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/messaging/service-worker.js b/messaging/service-worker.js index c0f875bb..1a202159 100644 --- a/messaging/service-worker.js +++ b/messaging/service-worker.js @@ -10,8 +10,9 @@ function initInSw() { // Give the service worker access to Firebase Messaging. // Note that you can only use Firebase Messaging here. Other Firebase libraries // are not available in the service worker. - importScripts('https://www.gstatic.com/firebasejs/8.10.1/firebase-app.js'); - importScripts('https://www.gstatic.com/firebasejs/8.10.1/firebase-messaging.js'); + // Replace 10.13.2 with latest version of the Firebase JS SDK. + importScripts('https://www.gstatic.com/firebasejs/10.13.2/firebase-app-compat.js'); + importScripts('https://www.gstatic.com/firebasejs/10.13.2/firebase-messaging-compat.js'); // Initialize the Firebase app in the service worker by passing in // your app's Firebase config object. From 3d04522869ad402c4da3ae74d6b30a4dbf8d1233 Mon Sep 17 00:00:00 2001 From: Athira M Date: Fri, 24 Jan 2025 12:17:10 +0530 Subject: [PATCH 8/9] RC doc update to provide default prod value for minimumFetchIntervalMillis (#389) * Add comment to highlight the default prod value for minimumFetchIntervalMillis. Issue addressed: https://github.com/firebase/firebase-js-sdk/issues/2841 * Update code snipped with default prod value for minimumFetchIntervalMillis. * Update code snipped with default prod value for minimumFetchIntervalMillis. * Update code snipped with default prod value for minimumFetchIntervalMillis. --------- Co-authored-by: Athira M --- remoteconfig-next/index.js | 1 + snippets/remoteconfig-next/index/rc_set_minimum_fetch_time.js | 1 + 2 files changed, 2 insertions(+) diff --git a/remoteconfig-next/index.js b/remoteconfig-next/index.js index aeeb263a..287f3c99 100644 --- a/remoteconfig-next/index.js +++ b/remoteconfig-next/index.js @@ -14,6 +14,7 @@ function getInstance() { function setMinimumFetchTime() { const remoteConfig = getInstance(); // [START rc_set_minimum_fetch_time] + // The default and recommended production fetch interval for Remote Config is 12 hours remoteConfig.settings.minimumFetchIntervalMillis = 3600000; // [END rc_set_minimum_fetch_time] } diff --git a/snippets/remoteconfig-next/index/rc_set_minimum_fetch_time.js b/snippets/remoteconfig-next/index/rc_set_minimum_fetch_time.js index 131976c5..77aa9f45 100644 --- a/snippets/remoteconfig-next/index/rc_set_minimum_fetch_time.js +++ b/snippets/remoteconfig-next/index/rc_set_minimum_fetch_time.js @@ -5,5 +5,6 @@ // 'npm run snippets'. // [START rc_set_minimum_fetch_time_modular] +// The default and recommended production fetch interval for Remote Config is 12 hours remoteConfig.settings.minimumFetchIntervalMillis = 3600000; // [END rc_set_minimum_fetch_time_modular] \ No newline at end of file From 467eaa165dcbd9b3ab15711e76fa52237ba37f8b Mon Sep 17 00:00:00 2001 From: "Nhien (Ricky) Lam" <62775270+NhienLam@users.noreply.github.com> Date: Thu, 6 Feb 2025 15:39:06 -0800 Subject: [PATCH 9/9] Update email link auth snippet to stop using deprecated `dynamicLinkDomain` (#390) * Update email link auth snippet to remove FDL * Update custom domain example --- auth-next/email-link-auth.js | 3 ++- .../email-link-auth/auth_email_link_actioncode_settings.js | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/auth-next/email-link-auth.js b/auth-next/email-link-auth.js index 4748e699..fde67663 100644 --- a/auth-next/email-link-auth.js +++ b/auth-next/email-link-auth.js @@ -19,7 +19,8 @@ function emailLinkActionCodeSettings() { installApp: true, minimumVersion: '12' }, - dynamicLinkDomain: 'example.page.link' + // The domain must be configured in Firebase Hosting and owned by the project. + linkDomain: 'custom-domain.com' }; // [END auth_email_link_actioncode_settings] } diff --git a/snippets/auth-next/email-link-auth/auth_email_link_actioncode_settings.js b/snippets/auth-next/email-link-auth/auth_email_link_actioncode_settings.js index a1480a11..010b5c09 100644 --- a/snippets/auth-next/email-link-auth/auth_email_link_actioncode_settings.js +++ b/snippets/auth-next/email-link-auth/auth_email_link_actioncode_settings.js @@ -19,6 +19,7 @@ const actionCodeSettings = { installApp: true, minimumVersion: '12' }, - dynamicLinkDomain: 'example.page.link' + // The domain must be configured in Firebase Hosting and owned by the project. + linkDomain: 'custom-domain.com' }; // [END auth_email_link_actioncode_settings_modular] \ No newline at end of file