Skip to content

Commit

Permalink
Add a sample for streaming callables (#1185)
Browse files Browse the repository at this point in the history
  • Loading branch information
jhuleatt authored Feb 3, 2025
1 parent 26c4b78 commit 814a99a
Show file tree
Hide file tree
Showing 10 changed files with 5,267 additions and 0 deletions.
299 changes: 299 additions & 0 deletions Node/pnpm-lock.yaml

Large diffs are not rendered by default.

66 changes: 66 additions & 0 deletions Node/quickstarts/callable-functions-streaming/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
firebase-debug.log*
firebase-debug.*.log*

# Firebase cache
.firebase/

# Firebase config

# Uncomment this if you'd like others to create their own Firebase project.
# For a team working on the same Firebase project(s), it is recommended to leave
# it commented so all members can deploy to the same project(s) in .firebaserc.
# .firebaserc

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# nyc test coverage
.nyc_output

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env
19 changes: 19 additions & 0 deletions Node/quickstarts/callable-functions-streaming/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
Firebase HTTPS Callable functions streaming quickstart
================================================

This quickstart demonstrates how to send requests to a server-side function and _stream_ a response to a client SDK.

[Read more about Cloud Functions for Firebase](https://firebase.google.com/docs/functions/)


Getting Started
---------------

1. Install dependencies with `npm install`
1. Start the hosting and functions emulators with `firebase emulators:start --only functions,hosting`
1. Visit the url of the emulated Hosting site, and click "Get forecasts"

License
-------

© Google, 2025. Licensed under an [Apache-2](../../../LICENSE) license.
11 changes: 11 additions & 0 deletions Node/quickstarts/callable-functions-streaming/firebase.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"functions": {
"codebase": "callable-functions",
"predeploy": [
"npm --prefix \"$RESOURCE_DIR\" run lint"
]
},
"hosting": {
"public": "website"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* Copyright 2023 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

module.exports = {
root: true,
env: {
es2020: true,
node: true,
},
extends: [
"eslint:recommended",
"google",
],
rules: {
quotes: ["error", "double"],
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules/
74 changes: 74 additions & 0 deletions Node/quickstarts/callable-functions-streaming/functions/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/**
* Copyright 2022 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

// [START full-sample]
// Dependencies for callable functions.
const {onCall, HttpsError} = require("firebase-functions/v2/https");

/**
* Gets the weather from the national weather service
* https://www.weather.gov/documentation/services-web-api
*
* @param {number} lat
* @param {number} lng
*/
async function weatherForecastApi(lat, lng) {
const resp = await fetch(`https://api.weather.gov/points/${lat},${lng}`);

if (!resp.ok) {
return `error: ${resp.status}`;
}

const forecastUrl = (await resp.json()).properties.forecast;
const forecastResp = await fetch(forecastUrl);

if (!forecastResp.ok) {
return `error: ${forecastResp.status}`;
}

// add an artificial wait to emphasize stream-iness
await new Promise((resolve) => setTimeout(resolve, Math.random() * 1500));

return forecastResp.json();
}

// [START streaming-callable]
exports.getForecast = onCall(async (request, response) => {
if (request.data?.locations?.length < 1) {
throw new HttpsError("invalid-argument", "Missing locations to forecast");
}

// fetch forecast data for all requested locations
const allRequests = request.data.locations.map(
async ({latitude, longitude}) => {
const forecast = await weatherForecastApi(latitude, longitude);
const result = {latitude, longitude, forecast};

// clients that support streaming will have each
// forecast streamed to them as they complete
if (request.acceptsStreaming) {
response.sendChunk(result);
}

return result;
},
);

// Return the full set of data to all clients
return Promise.all(allRequests);
});
// [END streaming-callable]
// [END full-sample]
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"name": "callable-functions-streaming",
"description": "Cloud Functions for Firebase",
"scripts": {
"lint": "eslint .",
"lintfix": "eslint . --fix",
"serve": "firebase emulators:start --only functions",
"shell": "firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log",
"compile": "cp ../../../../tsconfig.template.json ./tsconfig-compile.json && tsc --project tsconfig-compile.json"
},
"engines": {
"node": "22"
},
"main": "index.js",
"dependencies": {
"firebase-admin": "^13.0.2",
"firebase-functions": "^6.3.1"
},
"devDependencies": {
"eslint": "^8.57.1",
"eslint-config-google": "^0.14.0",
"firebase-functions-test": "^3.4.0"
},
"private": true
}
Loading

0 comments on commit 814a99a

Please sign in to comment.