diff --git a/Node-1st-gen/authenticated-json-api/functions/index.js b/Node-1st-gen/authenticated-json-api/functions/index.js index 39aaecaed6..3dd431a7aa 100644 --- a/Node-1st-gen/authenticated-json-api/functions/index.js +++ b/Node-1st-gen/authenticated-json-api/functions/index.js @@ -17,12 +17,14 @@ 'use strict'; const functions = require('firebase-functions/v1'); -const admin = require('firebase-admin'); +const { initializeApp, applicationDefault } = require('firebase-admin/app'); +const { getAuth } = require('firebase-admin/auth'); +const { getDatabase } = require('firebase-admin/database'); // Follow instructions to set up admin credentials: // https://firebase.google.com/docs/functions/local-emulator#set_up_admin_credentials_optional -admin.initializeApp({ - credential: admin.credential.applicationDefault(), +initializeApp({ + credential: applicationDefault(), // TODO: ADD YOUR DATABASE URL databaseURL: undefined }); @@ -44,7 +46,7 @@ const authenticate = async (req, res, next) => { } const idToken = req.headers.authorization.split('Bearer ')[1]; try { - const decodedIdToken = await admin.auth().verifyIdToken(idToken); + const decodedIdToken = await getAuth().verifyIdToken(idToken); req.user = decodedIdToken; next(); return; @@ -74,7 +76,7 @@ app.post('/api/messages', async (req, res) => { // @ts-ignore const uid = req.user.uid; - await admin.database().ref(`/users/${uid}/messages`).push(data); + await getDatabase().ref(`/users/${uid}/messages`).push(data); res.status(201).json({message, category}); } catch(error) { @@ -94,8 +96,8 @@ app.get('/api/messages', async (req, res) => { const uid = req.user.uid; const category = `${req.query?.category ?? ''}`; - /** @type admin.database.Query */ - let query = admin.database().ref(`/users/${uid}/messages`); + /** @type {import('firebase-admin/database').Query} */ + let query = getDatabase().ref(`/users/${uid}/messages`); if (category && ['positive', 'negative', 'neutral'].indexOf(category) > -1) { // Update the query with the valid category @@ -129,7 +131,7 @@ app.get('/api/message/:messageId', async (req, res) => { try { // @ts-ignore const uid = req.user.uid; - const snapshot = await admin.database().ref(`/users/${uid}/messages/${messageId}`).once('value'); + const snapshot = await getDatabase().ref(`/users/${uid}/messages/${messageId}`).once('value'); if (!snapshot.exists()) { return res.status(404).json({errorCode: 404, errorMessage: `message '${messageId}' not found`}); diff --git a/Node-1st-gen/convert-images/functions/index.js b/Node-1st-gen/convert-images/functions/index.js index e40890c5ee..4c418b33e0 100644 --- a/Node-1st-gen/convert-images/functions/index.js +++ b/Node-1st-gen/convert-images/functions/index.js @@ -16,13 +16,14 @@ 'use strict'; const functions = require('firebase-functions/v1'); -const admin = require('firebase-admin'); +const { initializeApp } = require('firebase-admin/app'); +const { getStorage } = require('firebase-admin/storage'); const spawn = require('child-process-promise').spawn; const path = require('path'); const os = require('os'); const fs = require('fs'); -admin.initializeApp(); +initializeApp(); // File extension for the created JPEG files. const JPEG_EXTENSION = '.jpg'; @@ -52,7 +53,7 @@ exports.imageToJPG = functions.storage.object().onFinalize(async (object) => { return null; } - const bucket = admin.storage().bucket(object.bucket); + const bucket = getStorage().bucket(object.bucket); // Create the temp directory where the storage file will be downloaded. await fs.promises.mkdir(tempLocalDir, { recursive: true }); // Download file from bucket. diff --git a/Node-1st-gen/coupon-on-purchase/functions/index.js b/Node-1st-gen/coupon-on-purchase/functions/index.js index bfdb691f57..07c8638bb2 100644 --- a/Node-1st-gen/coupon-on-purchase/functions/index.js +++ b/Node-1st-gen/coupon-on-purchase/functions/index.js @@ -16,8 +16,10 @@ 'use strict'; const functions = require('firebase-functions/v1'); -const admin = require('firebase-admin'); -admin.initializeApp(); +const { initializeApp } = require('firebase-admin/app'); +const { getMessaging } = require('firebase-admin/messaging'); +const { getDatabase } = require('firebase-admin/database'); +initializeApp(); // [START all] /** @@ -70,7 +72,7 @@ async function sendCouponViaFCM(uid, userLanguage) { } // Send notifications to all tokens. - return admin.messaging().sendEachForMulticast({ + return getMessaging().sendEachForMulticast({ notification: payload.notification, tokens }); @@ -107,7 +109,7 @@ async function sendHighValueCouponViaFCM(uid, userLanguage) { } // Send notifications to all tokens. - return admin.messaging().sendEachForMulticast({ + return getMessaging().sendEachForMulticast({ notification: payload.notification, tokens }); @@ -121,7 +123,7 @@ async function sendHighValueCouponViaFCM(uid, userLanguage) { * @param {string} uid The UID of the user. */ async function getDeviceTokens(uid) { - const snap = await admin.database().ref(`/users/${uid}/tokens`).once('value'); + const snap = await getDatabase().ref(`/users/${uid}/tokens`).once('value'); if (snap.exists()) { return Object.keys(snap.val()); } diff --git a/Node-1st-gen/delete-unused-accounts-cron/functions/index.js b/Node-1st-gen/delete-unused-accounts-cron/functions/index.js index c912b60518..6f10cc8b40 100644 --- a/Node-1st-gen/delete-unused-accounts-cron/functions/index.js +++ b/Node-1st-gen/delete-unused-accounts-cron/functions/index.js @@ -16,8 +16,9 @@ 'use strict'; const functions = require('firebase-functions/v1'); -const admin = require('firebase-admin'); -admin.initializeApp(); +const { initializeApp } = require('firebase-admin/app'); +const { getAuth } = require('firebase-admin/auth'); +initializeApp(); const PromisePool = require('es6-promise-pool').default; // Maximum concurrent account deletions. const MAX_CONCURRENT = 3; @@ -45,7 +46,7 @@ function deleteInactiveUser(inactiveUsers) { const userToDelete = inactiveUsers.pop(); // Delete the inactive user. - return admin.auth().deleteUser(userToDelete.uid).then(() => { + return getAuth().deleteUser(userToDelete.uid).then(() => { return functions.logger.log( 'Deleted user account', userToDelete.uid, @@ -68,7 +69,7 @@ function deleteInactiveUser(inactiveUsers) { * Returns the list of all inactive users. */ async function getInactiveUsers(users = [], nextPageToken) { - const result = await admin.auth().listUsers(1000, nextPageToken); + const result = await getAuth().listUsers(1000, nextPageToken); // Find users that have not signed in in the last 30 days. const inactiveUsers = result.users.filter( user => Date.parse(user.metadata.lastRefreshTime || user.metadata.lastSignInTime) < (Date.now() - 30 * 24 * 60 * 60 * 1000)); diff --git a/Node-1st-gen/developer-motivator/functions/index.js b/Node-1st-gen/developer-motivator/functions/index.js index c79bd860cb..7d69fe088a 100644 --- a/Node-1st-gen/developer-motivator/functions/index.js +++ b/Node-1st-gen/developer-motivator/functions/index.js @@ -15,10 +15,11 @@ */ 'use strict'; -const admin = require('firebase-admin'); +const { initializeApp } = require('firebase-admin/app'); +const { getMessaging } = require('firebase-admin/messaging'); const functions = require('firebase-functions/v1'); const {defineSecret} = require('firebase-functions/params'); -admin.initializeApp(); +initializeApp(); // TODO: Make sure you configure the 'DEV_MOTIVATOR_DEVICE_TOKEN' secret. const devMotivatorDeviceToken = defineSecret('DEV_MOTIVATOR_DEVICE_TOKEN'); @@ -37,7 +38,7 @@ exports.appinstalled = functions.runWith({secrets: [devMotivatorDeviceToken]}).a } }; - return admin.messaging().send({token: devMotivatorDeviceToken.value(), notification: payload.notification}); + return getMessaging().send({token: devMotivatorDeviceToken.value(), notification: payload.notification}); }); /** @@ -56,5 +57,5 @@ exports.appremoved = functions.runWith({secrets: [devMotivatorDeviceToken]}).ana } }; - return admin.messaging().send({token: devMotivatorDeviceToken.value(), notification: payload.notification}); + return getMessaging().send({token: devMotivatorDeviceToken.value(), notification: payload.notification}); }); diff --git a/Node-1st-gen/exif-images/functions/index.js b/Node-1st-gen/exif-images/functions/index.js index c85c4a2991..e22fcde07f 100644 --- a/Node-1st-gen/exif-images/functions/index.js +++ b/Node-1st-gen/exif-images/functions/index.js @@ -21,8 +21,9 @@ const crypto = require('crypto'); const path = require('path'); const os = require('os'); -const admin = require('firebase-admin'); -admin.initializeApp(); +const { initializeApp } = require('firebase-admin/app'); +const { getDatabase } = require('firebase-admin/database'); +initializeApp(); const { Storage } = require('@google-cloud/storage'); const spawn = require('child-process-promise').spawn; @@ -54,7 +55,7 @@ exports.metadata = functions.storage.object().onFinalize(async (object) => { // Save metadata to realtime datastore. metadata = imageMagickOutputToObject(result.stdout); const safeKey = makeKeyFirebaseCompatible(filePath); - await admin.database().ref(safeKey).set(metadata); + await getDatabase().ref(safeKey).set(metadata); functions.logger.log('Wrote to:', filePath, 'data:', metadata); // Cleanup temp directory after metadata is extracted // Remove the file from temp directory diff --git a/Node-1st-gen/fcm-notifications/functions/index.js b/Node-1st-gen/fcm-notifications/functions/index.js index d71fa9ce42..71a765e144 100644 --- a/Node-1st-gen/fcm-notifications/functions/index.js +++ b/Node-1st-gen/fcm-notifications/functions/index.js @@ -16,8 +16,11 @@ 'use strict'; const functions = require('firebase-functions/v1'); -const admin = require('firebase-admin'); -admin.initializeApp(); +const { initializeApp } = require('firebase-admin/app'); +const { getAuth } = require('firebase-admin/auth'); +const { getDatabase } = require('firebase-admin/database'); +const { getMessaging } = require('firebase-admin/messaging'); +initializeApp(); /** * Triggers when a user gets a new follower and sends a notification. @@ -46,11 +49,11 @@ exports.sendFollowerNotification = functions.database.ref('/followers/{followedU ); // Get the list of device notification tokens. - const getDeviceTokensPromise = admin.database() + const getDeviceTokensPromise = getDatabase() .ref(`/users/${followedUid}/notificationTokens`).once('value'); // Get the follower profile. - const getFollowerProfilePromise = admin.auth().getUser(followerUid); + const getFollowerProfilePromise = getAuth().getUser(followerUid); // The snapshot to the user's tokens. let tokensSnapshot; @@ -87,7 +90,7 @@ exports.sendFollowerNotification = functions.database.ref('/followers/{followedU // Listing all tokens as an array. tokens = Object.keys(tokensSnapshot.val()); // Send notifications to all tokens. - const {responses} = await admin.messaging().sendEachForMulticast({ + const {responses} = await getMessaging().sendEachForMulticast({ notification: payload.notification, tokens, }); diff --git a/Node-1st-gen/fulltext-search-firestore/functions/elastic.js b/Node-1st-gen/fulltext-search-firestore/functions/elastic.js index f8eaf4f0ae..29c1ea69f5 100644 --- a/Node-1st-gen/fulltext-search-firestore/functions/elastic.js +++ b/Node-1st-gen/fulltext-search-firestore/functions/elastic.js @@ -33,9 +33,11 @@ onInit(() => { client = new Client({ cloud: { id: elasticId.value(), + }, + auth: { username: elasticUsername.value(), password: elasticPassword.value(), - } + }, }); }); // [END init_elastic] diff --git a/Node-1st-gen/fulltext-search-firestore/functions/index.js b/Node-1st-gen/fulltext-search-firestore/functions/index.js index 4aeddfa452..f3321c6a6d 100644 --- a/Node-1st-gen/fulltext-search-firestore/functions/index.js +++ b/Node-1st-gen/fulltext-search-firestore/functions/index.js @@ -51,8 +51,9 @@ exports.onNoteCreated = functions.runWith({secrets: [algoliaId, algoliaAdminKey] // [END update_index_function] // [START get_firebase_user] -const admin = require('firebase-admin'); -admin.initializeApp(); +const { initializeApp } = require('firebase-admin/app'); +const { getAuth } = require('firebase-admin/auth'); +initializeApp(); async function getFirebaseUser(req, res, next) { functions.logger.log('Check if request is authorized with Firebase ID token'); @@ -73,7 +74,7 @@ async function getFirebaseUser(req, res, next) { } try { - const decodedIdToken = await admin.auth().verifyIdToken(idToken); + const decodedIdToken = await getAuth().verifyIdToken(idToken); functions.logger.log('ID Token correctly decoded', decodedIdToken); req.user = decodedIdToken; return next(); diff --git a/Node-1st-gen/fulltext-search-firestore/functions/typesense.js b/Node-1st-gen/fulltext-search-firestore/functions/typesense.js index c66ec5169c..eadcc94c9e 100644 --- a/Node-1st-gen/fulltext-search-firestore/functions/typesense.js +++ b/Node-1st-gen/fulltext-search-firestore/functions/typesense.js @@ -31,7 +31,7 @@ onInit(() => { client = new Typesense.Client({ 'nodes': [{ 'host': 'xxx.a1.typesense.net', // where xxx is the ClusterID of your Typesense Cloud cluster - 'port': '443', + 'port': 443, 'protocol': 'https' }], 'apiKey': typesenseAdminApiKey.value(), diff --git a/Node-1st-gen/fulltext-search-firestore/public/index.js b/Node-1st-gen/fulltext-search-firestore/public/index.js index 914f53eaf0..f96c2eab07 100644 --- a/Node-1st-gen/fulltext-search-firestore/public/index.js +++ b/Node-1st-gen/fulltext-search-firestore/public/index.js @@ -52,7 +52,10 @@ function searchAlgoliaAuthenticated(query) { return firebase.auth().currentUser.getIdToken() .then(function(token) { // The token is then passed to our getSearchKey Cloud Function - return fetch('https://us-central1-' + PROJECT_ID + '.cloudfunctions.net/getSearchKey/', { + const searchKeyUrl = new URL( + `https://us-central1-${PROJECT_ID}.cloudfunctions.net/getSearchKey/` + ); + return fetch(searchKeyUrl, { headers: { Authorization: 'Bearer ' + token } }); }) diff --git a/Node-1st-gen/fulltext-search/functions/index.js b/Node-1st-gen/fulltext-search/functions/index.js index eb2e9fa065..d808e67803 100644 --- a/Node-1st-gen/fulltext-search/functions/index.js +++ b/Node-1st-gen/fulltext-search/functions/index.js @@ -18,8 +18,9 @@ const functions = require('firebase-functions/v1'); const {onInit} = require('firebase-functions/v1/init'); const {defineSecret} = require('firebase-functions/params'); -const admin = require('firebase-admin'); -admin.initializeApp(); +const { initializeApp } = require('firebase-admin/app'); +const { getDatabase } = require('firebase-admin/database'); +initializeApp(); // Authenticate to Algolia Database. // TODO: Make sure you configure the `ALGOLIA_APP_ID` and `ALGOLIA_API_KEY` secrets. @@ -62,5 +63,5 @@ exports.searchentry = functions.runWith({secrets: [algoliaAppId, algoliaApiKey]} '/search/last_query_timestamp': Date.parse(context.timestamp), }; updates[`/search/results/${key}`] = content; - return admin.database().ref().update(updates); + return getDatabase().ref().update(updates); }); diff --git a/Node-1st-gen/google-sheet-sync/functions/index.js b/Node-1st-gen/google-sheet-sync/functions/index.js index ccc3015aca..4564a86349 100644 --- a/Node-1st-gen/google-sheet-sync/functions/index.js +++ b/Node-1st-gen/google-sheet-sync/functions/index.js @@ -20,8 +20,9 @@ const functions = require('firebase-functions/v1'); const {onInit} = require('firebase-functions/v1/init'); const {defineString, defineSecret} = require('firebase-functions/params'); -const admin = require('firebase-admin'); -admin.initializeApp(); +const { initializeApp } = require('firebase-admin/app'); +const { getDatabase } = require('firebase-admin/database'); +initializeApp(); const {OAuth2Client} = require('google-auth-library'); const {google} = require('googleapis'); @@ -70,7 +71,7 @@ exports.oauthcallback = functions.runWith({secrets: [googleApiClientId, googleAp try { const { tokens } = await functionsOauthClient.getToken(code); // Now tokens contains an access_token and an optional refresh_token. Save them. - await admin.database().ref(DB_TOKEN_PATH).set(tokens); + await getDatabase().ref(DB_TOKEN_PATH).set(tokens); res.status(200).send('App successfully configured with new Credentials. ' + 'You can now close this page.'); } catch (error) { @@ -120,7 +121,7 @@ async function getAuthorizedClient() { functionsOauthClient.setCredentials(oauthTokens); return functionsOauthClient; } - const snapshot = await admin.database().ref(DB_TOKEN_PATH).once('value'); + const snapshot = await getDatabase().ref(DB_TOKEN_PATH).once('value'); oauthTokens = snapshot.val(); functionsOauthClient.setCredentials(oauthTokens); return functionsOauthClient; @@ -132,7 +133,7 @@ exports.testsheetwrite = functions.https.onRequest(async (req, res) => { const random2 = Math.floor(Math.random() * 100); const random3 = Math.floor(Math.random() * 100); const ID = new Date().getUTCMilliseconds(); - await admin.database().ref(`${watchedpathsDataPath.value()}/${ID}`).set({ + await getDatabase().ref(`${watchedpathsDataPath.value()}/${ID}`).set({ firstColumn: random1, secondColumn: random2, thirdColumn: random3, diff --git a/Node-1st-gen/image-maker/functions/clock.js b/Node-1st-gen/image-maker/functions/clock.js index f9ff6a25cc..9f356fd3e7 100644 --- a/Node-1st-gen/image-maker/functions/clock.js +++ b/Node-1st-gen/image-maker/functions/clock.js @@ -14,7 +14,6 @@ * limitations under the License. */ -const _ = require('lodash'); const getDefaultOpts = () => ({ strokes: { @@ -39,7 +38,11 @@ const getY = (angle) => { }; const clock = (ctx, colorOpts) => { - const colors = _.merge({}, getDefaultOpts(), colorOpts); + const defaultOpts = getDefaultOpts(); + const colors = { + strokes: Object.assign({}, defaultOpts.strokes, colorOpts && colorOpts.strokes), + fills: Object.assign({}, defaultOpts.fills, colorOpts && colorOpts.fills), + }; let x, y, i; const now = new Date(); diff --git a/Node-1st-gen/instagram-auth/functions/index.js b/Node-1st-gen/instagram-auth/functions/index.js index b0b48e9811..3e7cac3048 100644 --- a/Node-1st-gen/instagram-auth/functions/index.js +++ b/Node-1st-gen/instagram-auth/functions/index.js @@ -22,11 +22,13 @@ const cookieParser = require('cookie-parser'); const crypto = require('node:crypto'); // Firebase Setup -const admin = require('firebase-admin'); +const { initializeApp, cert } = require('firebase-admin/app'); +const { getAuth } = require('firebase-admin/auth'); +const { getDatabase } = require('firebase-admin/database'); // @ts-ignore const serviceAccount = require('./service-account.json'); -admin.initializeApp({ - credential: admin.credential.cert(serviceAccount), +initializeApp({ + credential: cert(serviceAccount), databaseURL: `https://${process.env.GCLOUD_PROJECT}.firebaseio.com`, }); @@ -37,6 +39,7 @@ const instagramClientId = defineSecret('INSTAGRAM_CLIENT_ID'); const instagramClientSecret = defineSecret('INSTAGRAM_CLIENT_SECRET'); const { AuthorizationCode } = require('simple-oauth2'); +let oauth2; onInit(() => { // Instagram OAuth 2 setup // TODO: Configure the `INSTAGRAM_CLIENT_ID` and `INSTAGRAM_CLIENT_SECRET` secrets. @@ -129,16 +132,16 @@ async function createFirebaseAccount(instagramID, displayName, photoURL, accessT const uid = `instagram:${instagramID}`; // Save the access token to the Firebase Realtime Database. - const databaseTask = admin.database().ref(`/instagramAccessToken/${uid}`).set(accessToken); + const databaseTask = getDatabase().ref(`/instagramAccessToken/${uid}`).set(accessToken); // Create or update the user account. - const userCreationTask = admin.auth().updateUser(uid, { + const userCreationTask = getAuth().updateUser(uid, { displayName: displayName, photoURL: photoURL, }).catch((error) => { // If user does not exists we create it. if (error.code === 'auth/user-not-found') { - return admin.auth().createUser({ + return getAuth().createUser({ uid: uid, displayName: displayName, photoURL: photoURL, @@ -150,7 +153,7 @@ async function createFirebaseAccount(instagramID, displayName, photoURL, accessT // Wait for all async task to complete then generate and return a custom auth token. await Promise.all([userCreationTask, databaseTask]); // Create a Firebase custom auth token. - const token = await admin.auth().createCustomToken(uid); + const token = await getAuth().createCustomToken(uid); functions.logger.log( 'Created Custom token for UID "', uid, diff --git a/Node-1st-gen/lastmodified-tracking/functions/index.js b/Node-1st-gen/lastmodified-tracking/functions/index.js index 8e4de5973c..61b4b08a3b 100644 --- a/Node-1st-gen/lastmodified-tracking/functions/index.js +++ b/Node-1st-gen/lastmodified-tracking/functions/index.js @@ -16,11 +16,12 @@ 'use strict'; const functions = require('firebase-functions/v1'); -const admin = require('firebase-admin'); -admin.initializeApp(); +const { initializeApp } = require('firebase-admin/app'); +const { getDatabase } = require('firebase-admin/database'); +initializeApp(); /** * This Function updates the `/lastmodified` with the timestamp of the last write to `/chat/$message`. */ exports.touch = functions.database.ref('/chat/{message}').onWrite( - (change, context) => admin.database().ref('/lastmodified').set(context.timestamp)); + (change, context) => getDatabase().ref('/lastmodified').set(context.timestamp)); diff --git a/Node-1st-gen/linkedin-auth/functions/index.js b/Node-1st-gen/linkedin-auth/functions/index.js index 03ab2a6f37..eb7ec51e13 100644 --- a/Node-1st-gen/linkedin-auth/functions/index.js +++ b/Node-1st-gen/linkedin-auth/functions/index.js @@ -23,11 +23,13 @@ const cookieParser = require('cookie-parser'); const crypto = require('crypto'); // Firebase Setup -const admin = require('firebase-admin'); +const { initializeApp, cert } = require('firebase-admin/app'); +const { getAuth } = require('firebase-admin/auth'); +const { getDatabase } = require('firebase-admin/database'); // @ts-ignore const serviceAccount = require('./service-account.json'); -admin.initializeApp({ - credential: admin.credential.cert(serviceAccount), +initializeApp({ + credential: cert(serviceAccount), databaseURL: `https://${process.env.GCLOUD_PROJECT}.firebaseio.com`, }); @@ -146,16 +148,16 @@ exports.token = functions.runWith({secrets: [linkedinClientId, linkedinClientSec */ async function createFirebaseAccount(linkedinID, displayName, photoURL, email, accessToken) { const uid = `linkedin:${linkedinID}`; - const databaseTask = admin.database().ref(`/linkedInAccessToken/${uid}`).set(accessToken); + const databaseTask = getDatabase().ref(`/linkedInAccessToken/${uid}`).set(accessToken); - const userCreationTask = admin.auth().updateUser(uid, { + const userCreationTask = getAuth().updateUser(uid, { displayName: displayName, photoURL: photoURL, email: email, emailVerified: true, }).catch((error) => { if (error.code === 'auth/user-not-found') { - return admin.auth().createUser({ + return getAuth().createUser({ uid: uid, displayName: displayName, photoURL: photoURL, @@ -167,7 +169,7 @@ async function createFirebaseAccount(linkedinID, displayName, photoURL, email, a }); await Promise.all([userCreationTask, databaseTask]); - const token = await admin.auth().createCustomToken(uid); + const token = await getAuth().createCustomToken(uid); functions.logger.log('Created Custom token for UID "', uid, '" Token:', token); return token; } diff --git a/Node-1st-gen/message-translation/functions/index.js b/Node-1st-gen/message-translation/functions/index.js index 65d1957794..64d4dafce9 100644 --- a/Node-1st-gen/message-translation/functions/index.js +++ b/Node-1st-gen/message-translation/functions/index.js @@ -16,8 +16,9 @@ 'use strict'; const functions = require('firebase-functions/v1'); -const admin = require('firebase-admin'); -admin.initializeApp(); +const { initializeApp } = require('firebase-admin/app'); +const { getDatabase } = require('firebase-admin/database'); +initializeApp(); const { TranslationServiceClient } = require('@google-cloud/translate'); const translate = new TranslationServiceClient(); @@ -42,7 +43,7 @@ exports.translate = functions.database.ref('/messages/{languageID}/{messageID}') sourceLanguageCode: context.params.languageID, targetLanguageCode: language }); - return admin.database().ref(`/messages/${language}/${snapshot.key}`).set({ + return getDatabase().ref(`/messages/${language}/${snapshot.key}`).set({ message: results[0], translated: true, }); diff --git a/Node-1st-gen/moderate-images/functions/index.js b/Node-1st-gen/moderate-images/functions/index.js index 8639724824..c1ca69acd7 100644 --- a/Node-1st-gen/moderate-images/functions/index.js +++ b/Node-1st-gen/moderate-images/functions/index.js @@ -17,8 +17,9 @@ // Firebase setup const functions = require('firebase-functions/v1'); -const admin = require('firebase-admin'); -admin.initializeApp(); +const { initializeApp } = require('firebase-admin/app'); +const { getStorage } = require('firebase-admin/storage'); +initializeApp(); // Node.js core modules const fs = require('fs'); @@ -76,7 +77,7 @@ exports.blurOffensiveImages = functions.storage.object().onFinalize(async (objec async function blurImage(filePath, bucketName, metadata) { const tempLocalFile = path.join(os.tmpdir(), filePath); const tempLocalDir = path.dirname(tempLocalFile); - const bucket = admin.storage().bucket(bucketName); + const bucket = getStorage().bucket(bucketName); // Create the temp directory where the storage file will be downloaded. await mkdirp(tempLocalDir, { recursive: true }); diff --git a/Node-1st-gen/okta-auth/functions/index.js b/Node-1st-gen/okta-auth/functions/index.js index 1a1d9e661d..4c55c6ad55 100644 --- a/Node-1st-gen/okta-auth/functions/index.js +++ b/Node-1st-gen/okta-auth/functions/index.js @@ -34,8 +34,9 @@ if (envCfg.parsed && envCfg.parsed.GOOGLE_APPLICATION_CREDENTIALS) { const functions = require('firebase-functions/v1'); const {onInit} = require('firebase-functions/v1/init'); const {defineString} = require('firebase-functions/params'); -const firebaseAdmin = require('firebase-admin'); -const firebaseApp = firebaseAdmin.initializeApp(); +const { initializeApp } = require('firebase-admin/app'); +const { getAuth } = require('firebase-admin/auth'); +initializeApp(); const oktaOrgUrl = defineString('OKTA_ORG_URL'); const OktaJwtVerifier = require('@okta/jwt-verifier'); @@ -85,7 +86,7 @@ app.get('/firebaseCustomToken', [cors, oktaAuth], async (req, res) => { const oktaUid = req.jwt.claims.uid; try { const firebaseToken = - await firebaseApp.auth().createCustomToken(oktaUid); + await getAuth().createCustomToken(oktaUid); res.send(firebaseToken); } catch (err) { functions.logger.error('Error minting token.', err); diff --git a/Node-1st-gen/paypal/functions/index.js b/Node-1st-gen/paypal/functions/index.js index 087fb86fdd..2989d92662 100644 --- a/Node-1st-gen/paypal/functions/index.js +++ b/Node-1st-gen/paypal/functions/index.js @@ -20,8 +20,9 @@ const {onInit} = require('firebase-functions/v1/init'); const {defineSecret} = require('firebase-functions/params'); const paypal = require('paypal-rest-sdk'); // firebase-admin SDK init -const admin = require('firebase-admin'); -admin.initializeApp(); +const { initializeApp } = require('firebase-admin/app'); +const { getDatabase } = require('firebase-admin/database'); +initializeApp(); const paypalClientId = defineSecret('PAYPAL_CLIENT_ID'); const paypalClientSecret = defineSecret('PAYPAL_CLIENT_SECRET'); @@ -112,7 +113,7 @@ exports.process = functions.runWith({secrets: [paypalClientId, paypalClientSecre // set paid status to True in RealTime Database const date = Date.now(); const uid = payment.transactions[0].description; - const ref = admin.database().ref('users/' + uid + '/'); + const ref = getDatabase().ref('users/' + uid + '/'); ref.push({ paid: true, // 'description': description, diff --git a/Node-1st-gen/presence-firestore/functions/index.js b/Node-1st-gen/presence-firestore/functions/index.js index f91e958640..6b16d56b1b 100644 --- a/Node-1st-gen/presence-firestore/functions/index.js +++ b/Node-1st-gen/presence-firestore/functions/index.js @@ -16,13 +16,14 @@ // [START presence_sync_function] const functions = require('firebase-functions/v1'); -const admin = require('firebase-admin'); -admin.initializeApp(); +const { initializeApp } = require('firebase-admin/app'); +const { getFirestore } = require('firebase-admin/firestore'); +initializeApp(); // Since this code will be running in the Cloud Functions environment // we call initialize Firestore without any arguments because it // detects authentication from the environment. -const firestore = admin.firestore(); +const firestore = getFirestore(); // Create a new function which is triggered on changes to /status/{uid} // Note: This is a Realtime Database trigger, *not* Firestore. diff --git a/Node-1st-gen/publish-model/functions/index.js b/Node-1st-gen/publish-model/functions/index.js index cd3e6d7bd2..6baac01e5c 100644 --- a/Node-1st-gen/publish-model/functions/index.js +++ b/Node-1st-gen/publish-model/functions/index.js @@ -16,10 +16,11 @@ 'use strict'; const functions = require('firebase-functions/v1'); -const admin = require('firebase-admin'); -admin.initializeApp(); +const { initializeApp } = require('firebase-admin/app'); +const { getMachineLearning } = require('firebase-admin/machine-learning'); +initializeApp(); -const ml = admin.machineLearning(); +const ml = getMachineLearning(); const path = require('path'); /** diff --git a/Node-1st-gen/quickstarts/auth-blocking-functions/functions/index.js b/Node-1st-gen/quickstarts/auth-blocking-functions/functions/index.js index d8deda2ba5..566cd4e62e 100644 --- a/Node-1st-gen/quickstarts/auth-blocking-functions/functions/index.js +++ b/Node-1st-gen/quickstarts/auth-blocking-functions/functions/index.js @@ -15,10 +15,11 @@ */ const {functions} = require("firebase-functions/v1"); -const {admin} = require("firebase-admin"); +const { initializeApp } = require("firebase-admin/app"); +const { getFirestore } = require("firebase-admin/firestore"); -admin.initializeApp(); -const db = admin.firestore(); +initializeApp(); +const db = getFirestore(); // [START v1ValidateNewUser] // [START v1beforeCreateFunctionTrigger] diff --git a/Node-1st-gen/quickstarts/taskqueues-backup-images/functions/index.js b/Node-1st-gen/quickstarts/taskqueues-backup-images/functions/index.js index 99a1c5129d..6b241cef9a 100644 --- a/Node-1st-gen/quickstarts/taskqueues-backup-images/functions/index.js +++ b/Node-1st-gen/quickstarts/taskqueues-backup-images/functions/index.js @@ -14,6 +14,7 @@ * limitations under the License. */ "use strict"; +const {URL, URLSearchParams} = require("node:url"); const path = require("path"); const functions = require('firebase-functions/v1'); const {initializeApp} = require("firebase-admin/app"); @@ -54,9 +55,11 @@ exports.backupApod = functions } logger.info(`Requesting data from apod api for date ${date}`); - let url = "https://api.nasa.gov/planetary/apod"; - url += `?date=${date}`; - url += `&api_key=${process.env.NASA_API_KEY}`; + const url = new URL("https://api.nasa.gov/planetary/apod"); + url.search = new URLSearchParams({ + date, + api_key: process.env.NASA_API_KEY || "", + }).toString(); const apiResp = await fetch(url); if (!apiResp.ok) { logger.warn( diff --git a/Node-1st-gen/quickstarts/thumbnails/functions/index.js b/Node-1st-gen/quickstarts/thumbnails/functions/index.js index 0a3f73970d..d4f71c1b7e 100644 --- a/Node-1st-gen/quickstarts/thumbnails/functions/index.js +++ b/Node-1st-gen/quickstarts/thumbnails/functions/index.js @@ -17,12 +17,13 @@ // [START import] const functions = require('firebase-functions/v1'); -const admin = require('firebase-admin'); -admin.initializeApp() +const { initializeApp } = require('firebase-admin/app'); +const { getStorage } = require('firebase-admin/storage'); +initializeApp(); const path = require('path'); //library for resizing images -const sharp = require('sharp'); +const sharp = /** @type {import('sharp').SharpConstructor} */ (/** @type {unknown} */ (require('sharp'))); // [END import] // [START generateThumbnail] @@ -55,7 +56,7 @@ exports.firstGenGenerateThumbnail = functions.storage.object().onFinalize(async // [START thumbnailGeneration] // Download file from bucket. - const bucket = admin.storage().bucket(fileBucket); + const bucket = getStorage().bucket(fileBucket); const metadata = { contentType: contentType, }; diff --git a/Node-1st-gen/quickstarts/uppercase-firestore/functions/index.js b/Node-1st-gen/quickstarts/uppercase-firestore/functions/index.js index c5033d399e..7282699d87 100644 --- a/Node-1st-gen/quickstarts/uppercase-firestore/functions/index.js +++ b/Node-1st-gen/quickstarts/uppercase-firestore/functions/index.js @@ -21,8 +21,9 @@ const functions = require('firebase-functions/v1'); // The Firebase Admin SDK to access Firestore. -const admin = require("firebase-admin"); -admin.initializeApp(); +const { initializeApp } = require("firebase-admin/app"); +const { getFirestore } = require("firebase-admin/firestore"); +initializeApp(); // [END import] // [START addMessage] @@ -35,8 +36,7 @@ exports.addMessage = functions.https.onRequest(async (req, res) => { const original = req.query.text; // [START adminSdkAdd] // Push the new message into Firestore using the Firebase Admin SDK. - const writeResult = await admin - .firestore() + const writeResult = await getFirestore() .collection("messages") .add({ original: original }); // Send back a message that we've successfully written the message diff --git a/Node-1st-gen/remote-config-diff/functions/index.js b/Node-1st-gen/remote-config-diff/functions/index.js index ef8e1c3d01..4d73139ecd 100644 --- a/Node-1st-gen/remote-config-diff/functions/index.js +++ b/Node-1st-gen/remote-config-diff/functions/index.js @@ -15,14 +15,14 @@ */ const functions = require('firebase-functions/v1'); -const admin = require('firebase-admin'); +const { initializeApp, applicationDefault } = require('firebase-admin/app'); const jsonDiff = require('json-diff'); -admin.initializeApp(); +initializeApp(); // [START remote_config_function] exports.showConfigDiff = functions.remoteConfig.onUpdate(versionMetadata => { - return admin.credential.applicationDefault().getAccessToken() + return applicationDefault().getAccessToken() .then(accessTokenObj => { return accessTokenObj.access_token; }) diff --git a/Node-1st-gen/spotify-auth/functions/index.js b/Node-1st-gen/spotify-auth/functions/index.js index 5275c4f991..a4e540b707 100644 --- a/Node-1st-gen/spotify-auth/functions/index.js +++ b/Node-1st-gen/spotify-auth/functions/index.js @@ -22,11 +22,13 @@ const cookieParser = require('cookie-parser'); const crypto = require('node:crypto'); // Firebase Setup -const admin = require('firebase-admin'); +const { initializeApp, cert } = require('firebase-admin/app'); +const { getDatabase } = require('firebase-admin/database'); +const { getAuth } = require('firebase-admin/auth'); // @ts-ignore const serviceAccount = require('./service-account.json'); -admin.initializeApp({ - credential: admin.credential.cert(serviceAccount), +initializeApp({ + credential: cert(serviceAccount), databaseURL: `https://${process.env.GCLOUD_PROJECT}.firebaseio.com`, }); @@ -130,10 +132,10 @@ async function createFirebaseAccount(spotifyID, displayName, photoURL, email, ac const uid = `spotify:${spotifyID}`; // Save the access token to the Firebase Realtime Database. - const databaseTask = admin.database().ref(`/spotifyAccessToken/${uid}`).set(accessToken); + const databaseTask = getDatabase().ref(`/spotifyAccessToken/${uid}`).set(accessToken); // Create or update the user account. - const userCreationTask = admin.auth().updateUser(uid, { + const userCreationTask = getAuth().updateUser(uid, { displayName: displayName, photoURL: photoURL, email: email, @@ -141,7 +143,7 @@ async function createFirebaseAccount(spotifyID, displayName, photoURL, email, ac }).catch((error) => { // If user does not exists we create it. if (error.code === 'auth/user-not-found') { - return admin.auth().createUser({ + return getAuth().createUser({ uid: uid, displayName: displayName, photoURL: photoURL, @@ -155,7 +157,7 @@ async function createFirebaseAccount(spotifyID, displayName, photoURL, email, ac // Wait for all async tasks to complete, then generate and return a custom auth token. await Promise.all([userCreationTask, databaseTask]); // Create a Firebase custom auth token. - const token = await admin.auth().createCustomToken(uid); + const token = await getAuth().createCustomToken(uid); functions.logger.log( 'Created Custom token for UID "', uid, diff --git a/Node-1st-gen/stripe/functions/index.js b/Node-1st-gen/stripe/functions/index.js index f3eea58846..5f9616c919 100644 --- a/Node-1st-gen/stripe/functions/index.js +++ b/Node-1st-gen/stripe/functions/index.js @@ -18,20 +18,21 @@ const functions = require('firebase-functions/v1'); const {onInit} = require('firebase-functions/v1/init'); const {defineSecret} = require('firebase-functions/params'); -const admin = require('firebase-admin'); -admin.initializeApp(); +const { initializeApp } = require('firebase-admin/app'); +const { getFirestore } = require('firebase-admin/firestore'); +initializeApp(); const { Logging } = require('@google-cloud/logging'); const logging = new Logging({ projectId: process.env.GCLOUD_PROJECT, }); -const { Stripe } = require('stripe'); +const Stripe = require('stripe'); const stripeSecret = defineSecret('STRIPE_SECRET'); let stripe; onInit(() => { stripe = new Stripe(stripeSecret.value(), { - apiVersion: '2020-08-27', + apiVersion: '2026-07-29.dahlia', }); }); @@ -45,7 +46,7 @@ exports.createStripeCustomer = functions.runWith({secrets: [stripeSecret]}).auth const intent = await stripe.setupIntents.create({ customer: customer.id, }); - await admin.firestore().collection('stripe_customers').doc(user.uid).set({ + await getFirestore().collection('stripe_customers').doc(user.uid).set({ customer_id: customer.id, setup_secret: intent.client_secret, }); @@ -147,11 +148,11 @@ exports.confirmStripePayment = functions.runWith({secrets: [stripeSecret]}).fire * When a user deletes their account, clean up after them */ exports.cleanupUser = functions.runWith({secrets: [stripeSecret]}).auth.user().onDelete(async (user) => { - const dbRef = admin.firestore().collection('stripe_customers'); + const dbRef = getFirestore().collection('stripe_customers'); const customer = (await dbRef.doc(user.uid).get()).data(); await stripe.customers.del(customer.customer_id); // Delete the customers payments & payment methods in firestore. - const batch = admin.firestore().batch(); + const batch = getFirestore().batch(); const paymetsMethodsSnapshot = await dbRef .doc(user.uid) .collection('payment_methods') diff --git a/Node-1st-gen/survey-app-update/functions/index.js b/Node-1st-gen/survey-app-update/functions/index.js index 48f4f14ccb..d68941618d 100644 --- a/Node-1st-gen/survey-app-update/functions/index.js +++ b/Node-1st-gen/survey-app-update/functions/index.js @@ -18,8 +18,9 @@ const functions = require('firebase-functions/v1'); const {onInit} = require('firebase-functions/v1/init'); const {defineString, defineSecret} = require('firebase-functions/params'); -const admin = require('firebase-admin'); -admin.initializeApp(); +const { initializeApp } = require('firebase-admin/app'); +const { getAuth } = require('firebase-admin/auth'); +initializeApp(); const nodemailer = require('nodemailer'); // Configure the email transport using the default SMTP transport and a GMail account. // For other types of transports such as Sendgrid see https://nodemailer.com/transports/ @@ -49,7 +50,7 @@ exports.sendAppUpdateSurvey = functions.runWith({secrets: [gmailPassword]}).anal // Fetch the email of the user. In this sample we assume that the app is using Firebase Auth and // has set the Firebase Analytics User ID to be the same as the Firebase Auth uid using the // setUserId API. - const user = await admin.auth().getUser(uid); + const user = await getAuth().getUser(uid); const email = user.email; const name = user.displayName; return sendSurveyEmail(email, name); diff --git a/Node-1st-gen/template-handlebars/functions/firebaseUser.js b/Node-1st-gen/template-handlebars/functions/firebaseUser.js index 6e44f88888..ff7484010e 100644 --- a/Node-1st-gen/template-handlebars/functions/firebaseUser.js +++ b/Node-1st-gen/template-handlebars/functions/firebaseUser.js @@ -15,7 +15,7 @@ */ 'use strict'; -const admin = require('firebase-admin'); +const { getAuth } = require('firebase-admin/auth'); const cookieParser = require('cookie-parser')(); const functions = require('firebase-functions/v1'); @@ -61,7 +61,7 @@ function getIdTokenFromRequest(req, res) { */ async function addDecodedIdTokenToRequest(idToken, req) { try { - const decodedIdToken = await admin.auth().verifyIdToken(idToken); + const decodedIdToken = await getAuth().verifyIdToken(idToken); req.user = decodedIdToken; functions.logger.log('ID Token correctly decoded', decodedIdToken); } catch (error) { diff --git a/Node-1st-gen/template-handlebars/functions/index.js b/Node-1st-gen/template-handlebars/functions/index.js index 56b26b9f68..aa89b33df1 100644 --- a/Node-1st-gen/template-handlebars/functions/index.js +++ b/Node-1st-gen/template-handlebars/functions/index.js @@ -16,8 +16,8 @@ 'use strict'; const functions = require('firebase-functions/v1'); -const admin = require('firebase-admin'); -admin.initializeApp(); +const { initializeApp } = require('firebase-admin/app'); +initializeApp(); const express = require('express'); const { engine } = require('express-handlebars'); diff --git a/Node-1st-gen/text-moderation/functions/index.js b/Node-1st-gen/text-moderation/functions/index.js index aef14e6d5b..8747e63bf7 100644 --- a/Node-1st-gen/text-moderation/functions/index.js +++ b/Node-1st-gen/text-moderation/functions/index.js @@ -16,7 +16,7 @@ 'use strict'; const functions = require('firebase-functions/v1'); -const Filter = require('bad-words'); +const { Filter } = require('bad-words'); const badWordsFilter = new Filter(); // Moderates messages by lowering all uppercase messages and removing swearwords. diff --git a/Node-1st-gen/username-password-auth/functions/index.js b/Node-1st-gen/username-password-auth/functions/index.js index 0a38ddc613..ad0e30eae4 100644 --- a/Node-1st-gen/username-password-auth/functions/index.js +++ b/Node-1st-gen/username-password-auth/functions/index.js @@ -21,11 +21,12 @@ const functions = require('firebase-functions/v1'); const cors = require('cors')({origin: true}); // Firebase Setup -const admin = require('firebase-admin'); +const { initializeApp, cert } = require('firebase-admin/app'); +const { getAuth } = require('firebase-admin/auth'); // @ts-ignore const serviceAccount = require('./service-account.json'); -admin.initializeApp({ - credential: admin.credential.cert(serviceAccount), +initializeApp({ + credential: cert(serviceAccount), databaseURL: `https://${process.env.GCLOUD_PROJECT}.firebaseio.com`, }); @@ -83,7 +84,7 @@ exports.auth = functions.https.onRequest((req, res) => { } // On success return the Firebase Custom Auth Token. - const firebaseToken = await admin.auth().createCustomToken(username); + const firebaseToken = await getAuth().createCustomToken(username); return handleResponse(username, 200, { token: firebaseToken }); }); } catch (error) { diff --git a/Node-1st-gen/username-password-auth/public/main.js b/Node-1st-gen/username-password-auth/public/main.js index fc8e01fd1e..d13f63ff05 100644 --- a/Node-1st-gen/username-password-auth/public/main.js +++ b/Node-1st-gen/username-password-auth/public/main.js @@ -83,7 +83,7 @@ Demo.prototype.signIn = function() { req.onerror = function() { err.innerText = 'Network error in Firebase Cloud Function call see developer console for details'; }; - var url = 'https://us-central1-' + getFirebaseProjectId() + '.cloudfunctions.net/auth'; + var url = new URL(`https://us-central1-${getFirebaseProjectId()}.cloudfunctions.net/auth`); req.open('POST', url, true); req.setRequestHeader('Content-Type', 'application/json'); req.send(JSON.stringify({ diff --git a/Node/app-distribution-feedback-to-jira/functions/index.js b/Node/app-distribution-feedback-to-jira/functions/index.js index e477bf33c7..b1010e1c10 100644 --- a/Node/app-distribution-feedback-to-jira/functions/index.js +++ b/Node/app-distribution-feedback-to-jira/functions/index.js @@ -17,6 +17,7 @@ import { onInAppFeedbackPublished} from "firebase-functions/alerts/appDistribution"; import {defineInt, defineSecret, defineString} from "firebase-functions/params"; +import {URL, URLSearchParams} from "node:url"; import logger from "firebase-functions/logger"; import {FormData} from "formdata-polyfill/esm.min.js"; @@ -119,7 +120,8 @@ async function uploadScreenshot(issueUri, screenshotUri) { const form = new FormData(); form.append("file", blob, "screenshot.png"); - const ulResponse = await fetch(issueUri + "/attachments", { + const attachmentsUrl = new URL(`${issueUri}/attachments`); + const ulResponse = await fetch(attachmentsUrl, { method: "POST", body: form, headers: { @@ -139,15 +141,17 @@ async function uploadScreenshot(issueUri, screenshotUri) { * @param {string} testerEmail Email address of tester who filed feedback */ async function lookupReporter(testerEmail) { - const response = - await fetch( - `${jiraUriConfig.value()}/rest/api/3/user/search` + - `?query=${testerEmail}`, { - method: "GET", - headers: { - "Authorization": authHeader(), - "Accept": "application/json", - }}); + const searchUrl = new URL( + `${jiraUriConfig.value()}/rest/api/3/user/search`, + ); + searchUrl.search = new URLSearchParams({query: testerEmail}).toString(); + const response = await fetch(searchUrl, { + method: "GET", + headers: { + "Authorization": authHeader(), + "Accept": "application/json", + }, + }); if (!response.ok) { logger.info(`Failed to find Jira user for '${testerEmail}':` + `${response.status} ${response.statusText}`); diff --git a/Node/delete-unused-accounts-cron/functions/index.js b/Node/delete-unused-accounts-cron/functions/index.js index 837735a065..e808df7f8a 100644 --- a/Node/delete-unused-accounts-cron/functions/index.js +++ b/Node/delete-unused-accounts-cron/functions/index.js @@ -22,8 +22,9 @@ const {onSchedule} = require("firebase-functions/scheduler"); const {logger} = require("firebase-functions"); // The Firebase Admin SDK to delete inactive users. -const admin = require("firebase-admin"); -admin.initializeApp(); +const {initializeApp} = require("firebase-admin/app"); +const {getAuth} = require("firebase-admin/auth"); +initializeApp(); // The es6-promise-pool to limit the concurrency of promises. const PromisePool = require("es6-promise-pool").default; @@ -52,7 +53,7 @@ exports.accountcleanup = onSchedule("every day 00:00", async (event) => { // [START deleteInactiveUser] /** * Deletes one inactive user from the list. - * @param {admin.auth.UserRecord[]} inactiveUsers + * @param {import("firebase-admin/auth").UserRecord[]} inactiveUsers * @return {null | Promise} */ function deleteInactiveUser(inactiveUsers) { @@ -60,7 +61,7 @@ function deleteInactiveUser(inactiveUsers) { const userToDelete = inactiveUsers.pop(); // Delete the inactive user. - return admin.auth().deleteUser(userToDelete.uid).then(() => { + return getAuth().deleteUser(userToDelete.uid).then(() => { return logger.log( "Deleted user account", userToDelete.uid, @@ -84,12 +85,12 @@ function deleteInactiveUser(inactiveUsers) { // Returns the list of all inactive users. /** * - * @param {admin.auth.UserRecord[]} [users] the current list of inactive users + * @param {import("firebase-admin/auth").UserRecord[]} [users] the current list of inactive users * @param {string} [nextPageToken] - * @return {Promise} + * @return {Promise} */ async function getInactiveUsers(users = [], nextPageToken) { - const result = await admin.auth().listUsers(1000, nextPageToken); + const result = await getAuth().listUsers(1000, nextPageToken); // Find users that have not signed in in the last 30 days. const inactiveUsers = result.users.filter( (user) => diff --git a/Node/instrument-with-opentelemetry/functions/index.js b/Node/instrument-with-opentelemetry/functions/index.js index b978fbefc9..a2213b545f 100644 --- a/Node/instrument-with-opentelemetry/functions/index.js +++ b/Node/instrument-with-opentelemetry/functions/index.js @@ -26,9 +26,10 @@ const db = getFirestore(); /** * Divide an array into chunks of `chunkSize` - * @param {any[]} arr - * @param {Number} chunkSize - * @return {Array>} + * @template T + * @param {T[]} arr + * @param {number} chunkSize + * @return {T[][]} */ function sliceIntoChunks(arr, chunkSize) { const res = []; diff --git a/Node/quickstarts/thumbnails/functions/index.js b/Node/quickstarts/thumbnails/functions/index.js index d657dddd2b..34052f042a 100644 --- a/Node/quickstarts/thumbnails/functions/index.js +++ b/Node/quickstarts/thumbnails/functions/index.js @@ -27,7 +27,7 @@ const logger = require("firebase-functions/logger"); const path = require("path"); // library for image resizing -const sharp = require("sharp"); +const sharp = /** @type {import('sharp').SharpConstructor} */ (/** @type {unknown} */ (require("sharp"))); initializeApp(); // [END v2storageAdditionalImports] diff --git a/Node/remote-config-diff/functions/index.js b/Node/remote-config-diff/functions/index.js index 7db0dbe59f..0853b6af8a 100644 --- a/Node/remote-config-diff/functions/index.js +++ b/Node/remote-config-diff/functions/index.js @@ -17,12 +17,13 @@ // [START all] // [START import] +const {URL, URLSearchParams} = require("node:url"); // The Cloud Functions for Firebase SDK to set up triggers and logging. const {onConfigUpdated} = require("firebase-functions/remoteConfig"); const logger = require("firebase-functions/logger"); // The Firebase Admin SDK to obtain access tokens. -const admin = require("firebase-admin"); -const app = admin.initializeApp(); +const {initializeApp, applicationDefault} = require("firebase-admin/app"); +initializeApp(); const jsonDiff = require("json-diff"); // [END import] @@ -30,13 +31,14 @@ const jsonDiff = require("json-diff"); exports.showconfigdiff = onConfigUpdated(async (event) => { try { // Obtain the access token from the Admin SDK - const accessTokenObj = await admin.credential.applicationDefault() + const accessTokenObj = await applicationDefault() .getAccessToken(); const accessToken = accessTokenObj.access_token; // Get the version number from the event object - const remoteConfigApi = "https://firebaseremoteconfig.googleapis.com/v1/" + - `projects/${app.options.projectId}/remoteConfig`; + const remoteConfigApi = new URL( + `https://firebaseremoteconfig.googleapis.com/v1/projects/${process.env.GCLOUD_PROJECT}/remoteConfig`, + ); const currentVersion = event.data.versionNumber; const prevVersion = currentVersion - 1; const templatePromises = []; diff --git a/Node/taskqueues-backup-images/functions/index.js b/Node/taskqueues-backup-images/functions/index.js index 6254b1d5cf..b058c7c5b5 100644 --- a/Node/taskqueues-backup-images/functions/index.js +++ b/Node/taskqueues-backup-images/functions/index.js @@ -22,6 +22,7 @@ const {getFunctions} = require("firebase-admin/functions"); const {logger} = require("firebase-functions"); // Dependencies for image backup. +const {URL, URLSearchParams} = require("node:url"); const path = require("path"); const {initializeApp} = require("firebase-admin/app"); const {getStorage} = require("firebase-admin/storage"); @@ -59,9 +60,11 @@ exports.backupapod = onTaskDispatched( ); } logger.info(`Requesting data from apod api for date ${date}`); - let url = "https://api.nasa.gov/planetary/apod"; - url += `?date=${date}`; - url += `&api_key=${process.env.NASA_API_KEY}`; + const url = new URL("https://api.nasa.gov/planetary/apod"); + url.search = new URLSearchParams({ + date, + api_key: process.env.NASA_API_KEY || "", + }).toString(); const apiResp = await fetch(url); if (!apiResp.ok) { logger.warn( @@ -115,11 +118,12 @@ async function getFunctionUrl(name, location="us-central1") { }); } const projectId = await auth.getProjectId(); - const url = "https://cloudfunctions.googleapis.com/v2beta/" + - `projects/${projectId}/locations/${location}/functions/${name}`; + const url = new URL( + `https://cloudfunctions.googleapis.com/v2beta/projects/${projectId}/locations/${location}/functions/${name}`, + ); const client = await auth.getClient(); - const res = await client.request({url}); + const res = await client.request({url: url.toString()}); const uri = res.data?.serviceConfig?.uri; if (!uri) { throw new Error(`Unable to retreive uri for function at ${url}`); diff --git a/Node/test-functions-mocha/functions/index.test.js b/Node/test-functions-mocha/functions/index.test.js index e1e8db92e8..4da400068c 100644 --- a/Node/test-functions-mocha/functions/index.test.js +++ b/Node/test-functions-mocha/functions/index.test.js @@ -14,6 +14,8 @@ * limitations under the License. */ +/// + const {logger} = require("firebase-functions"); const test = require("firebase-functions-test"); const {spy} = require("sinon"); diff --git a/Node/youtube/functions/index.ts b/Node/youtube/functions/index.ts index 152f06521e..89b8bdcfdc 100644 --- a/Node/youtube/functions/index.ts +++ b/Node/youtube/functions/index.ts @@ -16,7 +16,7 @@ import { onCall, CallableRequest } from "firebase-functions/https"; import { defineSecret } from "firebase-functions/params"; -import { google } from "googleapis"; +import { google, youtube_v3 } from "googleapis"; const youtubeApiKey = defineSecret("YOUTUBE_API_KEY"); @@ -60,7 +60,7 @@ export const getChannelInfo = onCall({ secrets: [youtubeApiKey] }, async (reques channelTitle: channel.snippet!.title, channelDescription: channel.snippet!.description, subscriberCount: channel.statistics!.subscriberCount, - recentVideos: videos.map((video: any) => { + recentVideos: videos.map((video: youtube_v3.Schema$SearchResult) => { return { videoTitle: video.snippet!.title, videoUrl: `https://www.youtube.com/watch?v=${video.id!.videoId}`, diff --git a/tsconfig.template.json b/tsconfig.template.json index c896ff99fe..5f10ef387b 100644 --- a/tsconfig.template.json +++ b/tsconfig.template.json @@ -5,7 +5,7 @@ "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ "lib": ["es2022", "dom", "webworker"], /* Specify library files to be included in the compilation. */ "allowJs": true, /* Allow javascript files to be compiled. */ - "checkJs": false, /* Report errors in .js files. */ + "checkJs": true, /* Report errors in .js files. */ "outDir": "./dist", /* Redirect output structure to the directory. */ "noEmit": true, /* Do not emit outputs. */ "resolveJsonModule": true, @@ -29,7 +29,9 @@ "noUnusedLocals": false, /* Report errors on unused locals. */ // "noUnusedParameters": true, /* Report errors on unused parameters. */ // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ - // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + "allowUnreachableCode": false, /* Report errors for unreachable code. */ + "allowUnusedLabels": false, /* Report errors for unused labels. */ "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */