exports.createBundle=functions.https.onRequest(async(request,response)=>{// Query the 50 latest storiesconstlatestStories=awaitdb.collection('stories').orderBy('timestamp','desc').limit(50).get();// Build the bundle from the query resultsconstbundleBuffer=db.bundle('latest-stories').add('latest-stories-query',latestStories).build();// Cache the response for up to 5 minutes;// see https://firebase.google.com/docs/hosting/manage-cacheresponse.set('Cache-Control','public, max-age=300, s-maxage=600');response.end(bundleBuffer);});
Java
packagecom.example;importcom.google.auth.oauth2.GoogleCredentials;importcom.google.cloud.firestore.Firestore;importcom.google.cloud.firestore.FirestoreBundle;importcom.google.cloud.firestore.Query.Direction;importcom.google.cloud.firestore.QuerySnapshot;importcom.google.cloud.functions.HttpFunction;importcom.google.cloud.functions.HttpRequest;importcom.google.cloud.functions.HttpResponse;importcom.google.firebase.FirebaseApp;importcom.google.firebase.FirebaseOptions;importcom.google.firebase.cloud.FirestoreClient;importjava.io.BufferedWriter;importjava.io.IOException;publicclassExampleFunctionimplementsHttpFunction{publicstaticFirebaseAppinitializeFirebase()throwsIOException{if(FirebaseApp.getApps().isEmpty()){FirebaseOptionsoptions=FirebaseOptions.builder().setCredentials(GoogleCredentials.getApplicationDefault()).setProjectId("YOUR-PROJECT-ID").build();FirebaseApp.initializeApp(options);}returnFirebaseApp.getInstance();}@Overridepublicvoidservice(HttpRequestrequest,HttpResponseresponse)throwsException{// Get a Firestore instanceFirebaseAppapp=initializeFirebase();Firestoredb=FirestoreClient.getFirestore(app);// Query the 50 latest storiesQuerySnapshotlatestStories=db.collection("stories").orderBy("timestamp",Direction.DESCENDING).limit(50).get().get();// Build the bundle from the query resultsFirestoreBundlebundle=db.bundleBuilder("latest-stores").add("latest-stories-query",latestStories).build();// Cache the response for up to 5 minutes// see https://firebase.google.com/docs/hosting/manage-cacheresponse.appendHeader("Cache-Control","public, max-age=300, s-maxage=600");// Write the bundle to the HTTP responseBufferedWriterwriter=response.getWriter();writer.write(newString(bundle.toByteBuffer().array()));}}
// If you are using module bundlers.importfirebasefrom"firebase/app";import"firebase/firestore";import"firebase/firestore/bundle"// This line enables bundle loading as a side effect.asyncfunctionfetchFromBundle(){// Fetch the bundle from Firebase Hosting, if the CDN cache is hit the 'X-Cache'// response header will be set to 'HIT'constresp=awaitfetch('/createBundle');// Load the bundle contents into the Firestore SDKawaitdb.loadBundle(resp.body);// Query the results from the cache// Note: omitting "source: cache" will query the Firestore backend.constquery=awaitdb.namedQuery('latest-stories-query');conststoriesSnap=awaitquery.get({source:'cache'});// Use the results// ...}
[[["わかりやすい","easyToUnderstand","thumb-up"],["問題の解決に役立った","solvedMyProblem","thumb-up"],["その他","otherUp","thumb-up"]],[["必要な情報がない","missingTheInformationINeed","thumb-down"],["複雑すぎる / 手順が多すぎる","tooComplicatedTooManySteps","thumb-down"],["最新ではない","outOfDate","thumb-down"],["翻訳に関する問題","translationIssue","thumb-down"],["サンプル / コードに問題がある","samplesCodeIssue","thumb-down"],["その他","otherDown","thumb-down"]],["最終更新日 2025-09-04 UTC。"],[],[],null,["\u003cbr /\u003e\n\nMany applications serve the same content to all users on first page load. For\nexample a news site may show the latest stories, or an e-commerce site may show\nthe best-selling items.\n\nIf this content is served from Cloud Firestore, each user will issue a new\nquery for the same results when they load the application. Because these\nresults are not cached between users, the application is slower and more\nexpensive than it needs to be.\n\nSolution: Bundles\n\nCloud Firestore bundles allow you to assemble data bundles from common query\nresults on the backend using the Firebase Admin SDK, and serve these\npre-computed blobs cached on a CDN. This gives your users a much\nfaster first load experience and reduces your Cloud Firestore query costs.\n\nIn this guide we will use Cloud Functions to generate bundles and\nFirebase Hosting to dynamically cache and serve bundle content. More\ninformation about bundles is available in the [guides](/docs/firestore/bundles).\n\nFirst create a simple public HTTP function to query the 50 latest \"stories\" and\nserve the result as a bundle. \n\nNode.js \n\n```javascript\nexports.createBundle = functions.https.onRequest(async (request, response) =\u003e {\n // Query the 50 latest stories\n const latestStories = await db.collection('stories')\n .orderBy('timestamp', 'desc')\n .limit(50)\n .get();\n\n // Build the bundle from the query results\n const bundleBuffer = db.bundle('latest-stories')\n .add('latest-stories-query', latestStories)\n .build();\n\n // Cache the response for up to 5 minutes;\n // see https://firebase.google.com/docs/hosting/manage-cache\n response.set('Cache-Control', 'public, max-age=300, s-maxage=600');\n\n response.end(bundleBuffer);\n});\n \n```\n\nJava \n\n```java\n\npackage com.example;\n\nimport com.google.auth.oauth2.GoogleCredentials;\nimport com.google.cloud.firestore.Firestore;\nimport com.google.cloud.firestore.FirestoreBundle;\nimport com.google.cloud.firestore.Query.Direction;\nimport com.google.cloud.firestore.QuerySnapshot;\nimport com.google.cloud.functions.HttpFunction;\nimport com.google.cloud.functions.HttpRequest;\nimport com.google.cloud.functions.HttpResponse;\nimport com.google.firebase.FirebaseApp;\nimport com.google.firebase.FirebaseOptions;\nimport com.google.firebase.cloud.FirestoreClient;\nimport java.io.BufferedWriter;\nimport java.io.IOException;\n\npublic class ExampleFunction implements HttpFunction {\n\n public static FirebaseApp initializeFirebase() throws IOException {\n if (FirebaseApp.getApps().isEmpty()) {\n FirebaseOptions options = FirebaseOptions.builder()\n .setCredentials(GoogleCredentials.getApplicationDefault())\n .setProjectId(\"YOUR-PROJECT-ID\")\n .build();\n\n FirebaseApp.initializeApp(options);\n }\n\n return FirebaseApp.getInstance();\n }\n\n @Override\n public void service(HttpRequest request, HttpResponse response) throws Exception {\n // Get a Firestore instance\n FirebaseApp app = initializeFirebase();\n Firestore db = FirestoreClient.getFirestore(app);\n\n // Query the 50 latest stories\n QuerySnapshot latestStories = db.collection(\"stories\")\n .orderBy(\"timestamp\", Direction.DESCENDING)\n .limit(50)\n .get()\n .get();\n\n // Build the bundle from the query results\n FirestoreBundle bundle = db.bundleBuilder(\"latest-stores\")\n .add(\"latest-stories-query\", latestStories)\n .build();\n\n // Cache the response for up to 5 minutes\n // see https://firebase.google.com/docs/hosting/manage-cache\n response.appendHeader(\"Cache-Control\", \"public, max-age=300, s-maxage=600\");\n\n // Write the bundle to the HTTP response\n BufferedWriter writer = response.getWriter();\n writer.write(new String(bundle.toByteBuffer().array()));\n }\n}\n \n```\n\nNext configure Firebase Hosting to serve and cache this Cloud Function by\nmodifying `firebase.json`. With this configuration the Firebase Hosting CDN\nwill serve the bundle content according to the cache settings set by the\nCloud Function. When the cache expires it will refresh the content by triggering\nthe function again. \n\n firebase.json\n {\n \"hosting\": {\n // ...\n \"rewrites\": [{\n \"source\": \"/createBundle\",\n \"function\": \"createBundle\"\n }]\n },\n // ...\n }\n\nFinally in your web application, fetch the bundled content from the CDN and load\nit into the Firestore SDK. \n\n // If you are using module bundlers.\n import firebase from \"firebase/app\";\n import \"firebase/firestore\";\n import \"firebase/firestore/bundle\" // This line enables bundle loading as a side effect.\n\n async function fetchFromBundle() {\n // Fetch the bundle from Firebase Hosting, if the CDN cache is hit the 'X-Cache'\n // response header will be set to 'HIT'\n const resp = await fetch('/createBundle');\n\n // Load the bundle contents into the Firestore SDK\n await db.loadBundle(resp.body);\n\n // Query the results from the cache\n // Note: omitting \"source: cache\" will query the Firestore backend.\n \n const query = await db.namedQuery('latest-stories-query');\n const storiesSnap = await query.get({ source: 'cache' });\n\n // Use the results\n // ...\n }\n\nEstimated Savings\n\nConsider a news website which gets 100,000 users per day and each user loads the\nsame 50 top stories on initial load. Without any caching, this would result in\n50 x 100,000 = 5,000,000 document reads per day from Cloud Firestore.\n\nNow assume the site adopts the technique above and caches those 50 results for\nup to 5 minutes. So instead of loading the query results for every user, the\nresults are loaded exactly 12 times per hour. No matter how many users arrive\nat the site, the number of queries to Cloud Firestore stays the same. Instead of\n5,000,000 document reads, this page would use 12 x 24 x 50 = 14,400 document\nreads per day. The small additional costs for Firebase Hosting and\nCloud Functions are easily offset by the Cloud Firestore cost savings.\n\nWhile the developer benefits from the cost savings, the biggest beneficiary is\nthe user. Loading these 50 documents from the Firebase Hosting CDN rather than\nfrom Cloud Firestore directly can easily shave 100-200ms or more from the\ncontent load time of the page. Studies have repeatedly shown that speedy pages\nmean happier users."]]