A simple web client demonstrating how to call Firebase Functions (both onRequest and onCall) using the Firebase JavaScript SDK.
- Start the Firebase emulator with the Dart functions:
cd ../basic
dart pub upgrade
dart run build_runner build --delete-conflicting-outputs
firebase emulators:start --only functions,auth- Note the Functions URL from the emulator output (usually
http://127.0.0.1:5001/demo-test/us-central1).
You can open index.html directly in a browser, or serve it with a local server:
# Using Python
python3 -m http.server 8000
# Using Node.js (npx)
npx serve .
# Using PHP
php -S localhost:8000Then open http://localhost:8000 in your browser.
Calls the helloWorld function using a simple fetch() request. This demonstrates how onRequest functions work like regular HTTP endpoints.
const response = await fetch(`${baseUrl}/helloWorld?name=World`);
const text = await response.text();Calls the greet function using the Firebase SDK's httpsCallable(). This handles authentication, CORS, and request/response formatting automatically.
import { getFunctions, httpsCallable } from 'firebase/functions';
const functions = getFunctions(app, 'us-central1');
const greet = httpsCallable(functions, 'greet');
const result = await greet({ name: 'Dart Developer' });
// result.data = { message: 'Hello, Dart Developer!' }Demonstrates how callable functions handle errors. The divide function throws structured errors for invalid input or division by zero.
Calls the greetTyped function which uses typed request/response classes on the server side.
Demonstrates extracting authentication data from callable function requests. The getAuthInfo function returns the authenticated user's information:
// Server-side (Dart)
firebase.https.onCall(name: 'getAuthInfo', (request, response) async {
final auth = request.auth;
if (auth == null) {
return CallableResult({
'authenticated': false,
'message': 'No authentication provided',
});
}
return CallableResult({
'authenticated': true,
'uid': auth.uid,
'token': auth.token, // Decoded JWT claims
});
});// Client-side (JavaScript)
import { getAuth, signInWithEmailAndPassword } from 'firebase/auth';
// Sign in first
const auth = getAuth(app);
await signInWithEmailAndPassword(auth, 'test@example.com', 'password123');
// Call the function - Firebase SDK automatically attaches the ID token
const getAuthInfo = httpsCallable(functions, 'getAuthInfo');
const result = await getAuthInfo({});
// result.data = { authenticated: true, uid: '...', token: { email: '...', ... } }The request.auth object contains:
uid- The user's unique Firebase UIDtoken- Decoded ID token claims (email, name, custom claims, etc.)rawToken- The raw JWT string (for passing to other services)
Shows how to call a callable function without the Firebase SDK using the callable protocol:
const response = await fetch(`${baseUrl}/greet`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ data: { name: 'Raw Caller' } })
});
const json = await response.json();
// json = { result: { message: 'Hello, Raw Caller!' } }The Firebase callable protocol wraps data in a specific format:
Request:
{
"data": { /* your input */ }
}Response:
{
"result": { /* function return value */ }
}Error:
{
"error": {
"status": "INVALID_ARGUMENT",
"message": "Error description"
}
}- CORS errors: Make sure you're running the Firebase emulator and the Functions URL is correct.
- Connection refused: Ensure the emulator is running on the expected port.
- Function not found: Verify the function names match between client and server.
- Auth not working: Make sure you started the emulator with
--only functions,auth.