From 7352ce24ff2b73baf2680105159d6763f6907570 Mon Sep 17 00:00:00 2001 From: rootkiller6788 Date: Thu, 17 Sep 2026 14:27:49 +0800 Subject: [PATCH 1/3] fix(functions): hand addNumbers/addMessage the whole v2 request firebase-functions v2 calls an onCall handler with a single CallableRequest ({data, auth, instanceIdToken}), not the old (data, context) pair. #1701 moved the sample to the v2 import path but kept the v1 handler shape, so addNumbers read data.firstNumber off the request wrapper and always answered invalid-argument, and addMessage blew up on context.auth. The androidTest TestAddNumber expects 32 + 16 = 48, which never came back. --- functions/functions/index.js | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/functions/functions/index.js b/functions/functions/index.js index 8dc7eecb09..317bcd6c22 100644 --- a/functions/functions/index.js +++ b/functions/functions/index.js @@ -25,12 +25,12 @@ initializeApp(); // [START allAdd] // [START addFunctionTrigger] // Adds two numbers to each other. -exports.addNumbers = onCall((data) => { +exports.addNumbers = onCall((request) => { // [END addFunctionTrigger] // [START readAddData] // Numbers passed from the client. - const firstNumber = data.firstNumber; - const secondNumber = data.secondNumber; + const firstNumber = request.data.firstNumber; + const secondNumber = request.data.secondNumber; // [END readAddData] // [START addHttpsError] @@ -56,11 +56,11 @@ exports.addNumbers = onCall((data) => { // [START messageFunctionTrigger] // Saves a message to the Firebase Realtime Database but sanitizes the text by removing swearwords. -exports.addMessage = onCall((data, context) => { +exports.addMessage = onCall((request) => { // [START_EXCLUDE] // [START readMessageData] // Message text passed from the client. - const text = data.text; + const text = request.data.text; // [END readMessageData] // [START messageHttpsErrors] // Checking attribute. @@ -70,7 +70,7 @@ exports.addMessage = onCall((data, context) => { 'one arguments "text" containing the message text to add.'); } // Checking that the user is authenticated. - if (!context.auth) { + if (!request.auth) { // Throwing an HttpsError so that the client gets the error details. throw new HttpsError('failed-precondition', 'The function must be called ' + 'while authenticated.'); @@ -79,10 +79,10 @@ exports.addMessage = onCall((data, context) => { // [START authIntegration] // Authentication / user information is automatically added to the request. - const uid = context.auth.uid; - const name = context.auth.token.name || null; - const picture = context.auth.token.picture || null; - const email = context.auth.token.email || null; + const uid = request.auth.uid; + const name = request.auth.token.name || null; + const picture = request.auth.token.picture || null; + const email = request.auth.token.email || null; // [END authIntegration] // [START returnMessageAsync] @@ -93,9 +93,9 @@ exports.addMessage = onCall((data, context) => { author: { uid, name, picture, email }, }).then(() => { // Optionally send a push notification with the message. - if (data.push && context.instanceIdToken) { + if (request.data.push && request.instanceIdToken) { return admin.messaging().send({ - token: context.instanceIdToken, + token: request.instanceIdToken, data: { text: sanitizedMessage }, }); } From 8f8583557db6f111f34be7f546084e1af081c3e6 Mon Sep 17 00:00:00 2001 From: rootkiller6788 Date: Thu, 17 Sep 2026 14:28:01 +0800 Subject: [PATCH 2/3] fix(functions): put back the sanitizer call and the admin imports Two things got lost in the same v2 pass. The require for firebase-admin went away while addMessage still called admin.database(), and the qualified call turned into a bare sanitizeText() that is not defined in this file. Both are ReferenceErrors at request time, so addMessage never once wrote a message. Switched to the modular admin entry points (firebase-admin/database, firebase-admin/messaging) to match the initializeApp import that is already here. --- functions/functions/index.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/functions/functions/index.js b/functions/functions/index.js index 317bcd6c22..edc35a8526 100644 --- a/functions/functions/index.js +++ b/functions/functions/index.js @@ -17,6 +17,8 @@ const {onCall, HttpsError} = require('firebase-functions/v2/https') const {initializeApp} = require("firebase-admin/app"); +const {getDatabase} = require('firebase-admin/database'); +const {getMessaging} = require('firebase-admin/messaging'); const sanitizer = require('./sanitizer'); @@ -87,14 +89,14 @@ exports.addMessage = onCall((request) => { // [START returnMessageAsync] // Saving the new message to the Realtime Database. - const sanitizedMessage = sanitizeText(text); // Sanitize the message. - return admin.database().ref('/messages').push({ + const sanitizedMessage = sanitizer.sanitizeText(text); // Sanitize the message. + return getDatabase().ref('/messages').push({ text: sanitizedMessage, author: { uid, name, picture, email }, }).then(() => { // Optionally send a push notification with the message. if (request.data.push && request.instanceIdToken) { - return admin.messaging().send({ + return getMessaging().send({ token: request.instanceIdToken, data: { text: sanitizedMessage }, }); From 846fcc2183f169ca3de7a9ac80481d1d3abdd12b Mon Sep 17 00:00:00 2001 From: rootkiller6788 Date: Mon, 5 Oct 2026 23:55:39 +0800 Subject: [PATCH 3/3] fix(functions): guard request.data before reading its fields A callable invoked without a body leaves data undefined, and reading firstNumber/text off it threw a TypeError instead of the intended invalid-argument HttpsError. Optional chaining lets the existing checks reject the call cleanly. --- functions/functions/index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/functions/functions/index.js b/functions/functions/index.js index edc35a8526..4b4fa68eb0 100644 --- a/functions/functions/index.js +++ b/functions/functions/index.js @@ -31,8 +31,8 @@ exports.addNumbers = onCall((request) => { // [END addFunctionTrigger] // [START readAddData] // Numbers passed from the client. - const firstNumber = request.data.firstNumber; - const secondNumber = request.data.secondNumber; + const firstNumber = request.data?.firstNumber; + const secondNumber = request.data?.secondNumber; // [END readAddData] // [START addHttpsError] @@ -62,7 +62,7 @@ exports.addMessage = onCall((request) => { // [START_EXCLUDE] // [START readMessageData] // Message text passed from the client. - const text = request.data.text; + const text = request.data?.text; // [END readMessageData] // [START messageHttpsErrors] // Checking attribute.