+++ UPDATE > SOLVED: The problem has been resolved. Solution > For particular custom code, you need to work in/with Visual Studio + FlutterFlow Visual Studio Extension. You create the code in VSE and push it to/compile in FF. Certain code FF's code editor can't handle. VSE works (if the code is valid, obviously), but you need to upgrade from the free plan. +++
https://docs.flutterflow.io/concepts/custom-code/vscode-extension/
********************************************************************
Hey all,
I have created several custom code snippets along the way, but I have not been successful with this one. Something is missing, or I have misinterpreted something; I can't figure out what.
I also tried to get help from Gemini and ChatGPT. They seem to think my minimal code (just a testing snippet) should work.
I leave screenshots from the settings, the code, and a screen recording.
If anyone could tell me what I'm doing wrong, I would be most appreciative!
Thank you ๐
BTW: I tried Nullable checked/unchecked and any other parameters, without success.
extractGeminiTextResponseV2
// Automatic FlutterFlow imports
import '/backend/backend.dart';import '/flutter_flow/flutter_flow_theme.dart';
import '/flutter_flow/flutter_flow_util.dart';
import '/custom_code/actions/index.dart'; // Imports other custom actions
import '/flutter_flow/custom_functions.dart'; // Imports custom functions
import 'package:flutter/material.dart';
// Begin custom action code
// DO NOT REMOVE OR MODIFY THE CODE ABOVE!
Future extractGeminiTextResponseV2() async {
dynamic apiResponseJson,
DocumentReference? analysisDocRef,
) async {
// This is a minimal test return to see if the signature parses
return {
'testKey': 'testValue',
};
}
https://www.loom.com/share/4965b7bfa510410f9f938daf61797cfe?sid=25a7144d-5790-418c-83dd-444a12529096
SAME TROUBLES AGAIN ๐ - all parameters + Return Value set correctly
import 'dart:convert';
import 'dart:math' as math;
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:intl/intl.dart';
import 'package:timeago/timeago.dart' as timeago;
import '/flutter_flow/custom_functions.dart';
import '/flutter_flow/lat_lng.dart';
import '/flutter_flow/place.dart';
import '/flutter_flow/uploaded_file.dart';
import '/backend/backend.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import '/auth/firebase_auth/auth_util.dart';
import 'package:http/http.dart' as http;
import 'package:flutter/widgets.dart';
// IMPORTANT: No 'Future<bool>' here. Just 'bool' as per FlutterFlow's UI return type setting.
// The 'async' keyword IS needed if you use 'await' inside the function.
Future<bool> sendBrevoEmailSecure( // Keeping Future<bool> because FlutterFlow's actions are often treated this way implicitly.
String apiKeyBrevo,
int templateId,
String senderEmail,
String senderName,
String recipientEmail,
String recipientName,
String emailSubject,
String contactType,
String userComment,
) async { // KEEP 'async' keyword as you are using 'await' inside.
final url = Uri.parse('https://api.brevo.com/v3/smtp/email'); //
final params = {
"senderName": senderName,
"contactType": contactType,
"userComment": userComment,
"recipientEmail": recipientEmail,
"senderEmail": senderEmail,
};
final body = jsonEncode({
"sender": {
"name": senderName,
"email": senderEmail,
},
"to": [
{
"email": recipientEmail,
"name": recipientName,
}
],
"replyTo": {
"email": senderEmail,
"name": senderName,
},
"templateId": templateId, //
"subject": emailSubject,
"params": params, //
});
try {
final response = await http.post(
url,
headers: {
'api-key': apiKeyBrevo,
'Content-Type': 'application/json', //
'Accept': 'application/json',
},
body: body,
);
if (response.statusCode >= 200 && response.statusCode < 300) {
debugPrint('Brevo Email Sent Successfully! Response: ${response.body}');
return true;
} else {
debugPrint('Brevo API Error: Status ${response.statusCode}, Body: ${response.body}');
return false;
}
} catch (e) {
debugPrint('Brevo API Exception: $e');
return false;
}
}
And yet another code that creates a parsing error...๐
import 'dart:convert';
import 'dart:math' as math;
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:intl/intl.dart';
import 'package:timeago/timeago.dart' as timeago;
import '/flutter_flow/custom_functions.dart';
import '/flutter_flow/lat_lng.dart';
import '/flutter_flow/place.dart';
import '/flutter_flow/uploaded_file.dart';
import '/backend/backend.dart';
import 'package:cloud_firestore/cloud_firestore.dart'; // <--- IMPORTANT IMPORT
import '/auth/firebase_auth/auth_util.dart';
// Make sure the return type is 'String?' to match nullable setting in FlutterFlow UI
String? getImageUrlFromDocument(DocumentSnapshot? document) {
/// MODIFY CODE ONLY BELOW THIS LINE
if (document == null || !document.exists) {
return null; // Return null if document is null or doesn't exist, as the return type is nullable
}
// Explicitly get the 'photo_url_anaysis' field.
// We use .get() which returns dynamic, then check its type.
// Be absolutely sure of the field name spelling: 'photo_url_anaysis' as seen in your Firestore
final dynamic imageUrl = document.get('photo_url_anaysis');
if (imageUrl is String) {
return imageUrl;
} else {
// If the field is not a string or doesn't exist/is null, return null
return null;
}
/// MODIFY CODE ONLY ABOVE THIS LINE
}