I’ve built a cloud function in JavaScript (node: 18) to use the Gemini AI in my Flutter app. This function generates a list of workouts that may be long enough to throw a “DEADLINE EXCEEDED” error. However, the function worked successfully (status code: 200), so the problem should be in the length of the response. In fact, the error is thrown by the bloc function from which I call the cloud function.
Here are the debug console, the could function, the bloc function and the function log.
Debug console:
[firebase_functions/deadline-exceeded] DEADLINE EXCEEDED
#0 StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:648:7)
#1 MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:334:18)
<asynchronous suspension>
#2 MethodChannelHttpsCallable.call (package:cloud_functions_platform_interface/src/method_channel/method_channel_https_callable.dart:22:24)
<asynchronous suspension>
#3 HttpsCallable.call (package:cloud_functions/src/https_callable.dart:49:37)
<asynchronous suspension>
#4 new GenerateWorkoutBloc.<anonymous closure> (package:energi/logic/blocs/generate_workout/generate_workout_bloc.dart:24:26)
<asynchronous suspension>
#5 Bloc.on.<anonymous closure>.handleEvent (package:bloc/src/bloc.dart:229:13)
<asynchronous suspension>
Cloud function:
const functions = require("firebase-functions");
const { GoogleGenerativeAI } = require("@google/generative-ai");
const { prompt } = require("./prompt.cjs");
const apiKey = "key";
const genAI = new GoogleGenerativeAI(apiKey);
const generationConfig = {
temperature: 0,
topP: 0.95,
topK: 64,
maxOutputTokens: 8192,
responseMimeType: "application/json",
responseSchema: {
type: "object",
properties: {
routine: {
type: "object",
properties: {
workoutList: {
type: "array",
items: {
type: "object",
properties: {
title: {
type: "string"
},
exerciseList: {
type: "array",
items: {
type: "object",
properties: {
exercise: {
type: "object",
properties: {
title: {
type: "string"
},
setList: {
type: "array",
items: {
type: "string"
}
},
timer: {
type: "integer"
},
id: {
type: "string"
}
},
required: [
"title",
"setList",
"timer",
"id"
]
}
},
required: [
"exercise"
]
}
}
},
required: [
"title",
"exerciseList"
]
}
}
},
required: [
"workoutList"
]
}
},
required: [
"routine"
]
},
};
const model = genAI.getGenerativeModel({
model: "gemini-1.5-flash",
generationConfig: generationConfig,
});
const runtimeOpts = {
timeoutSeconds: 300,
}
exports.generateWorkout = functions.runWith(runtimeOpts).https.onRequest(async (req, res) => {
try {
const content = await model.generateContent(prompt);
const response = content.response.text();
res.status(200).send({ data: response });
} catch (error) {
console.error(error);
res.status(500).send({ error: 'Internal Server Error' });
}
});
Bloc function:
on<Generate>((event, emit) async {
emit(GenerateWorkoutInProgress());
try {
HttpsCallable callable =
FirebaseFunctions.instance.httpsCallable('generateWorkout');
final response = await callable.call(<String, dynamic>{
"type": "object",
"properties": {
"routine": {
"type": "object",
"properties": {
"workoutList": {
"type": "array",
"items": {
"type": "object",
"properties": {
"title": {"type": "string"},
"exerciseList": {
"type": "array",
"items": {
"type": "object",
"properties": {
"exercise": {
"type": "object",
"properties": {
"title": {"type": "string"},
"setList": {
"type": "array",
"items": {"type": "string"}
},
"timer": {"type": "integer"},
"id": {"type": "string"}
}
}
}
}
}
}
}
}
}
}
}
});
final workouts = await fromAiData(
json.decode(response.data) as Map<String, dynamic>);
emit(GenerateWorkoutSuccess(workouts: workouts));
} on FirebaseFunctionsException catch (error) {
emit(GenerateWorkoutError());
print(error.toString());
} catch (error) {
emit(GenerateWorkoutError());
print(error.toString());
}
});
UPDATE: Here is the definition of the deadline exceeded error provided by the Firebase documentation:
deadline-exceeded: Deadline expired before operation could complete. For operations that change the state of the system, this error may be returned even if the operation has completed successfully. For example, a successful response from a server could have been delayed long enough for the deadline to expire.