To reduce firestore cost, I'm trying to introduce Firestore Data Bundles into my project.
I've tried some steps below.
1. Create Bundle txt file and upload it to GCS.
[Cloud Functions]
import { getAdmin } from "../../util/firebase";
import * as firebase from "firebase-admin";
import * as fs from "fs";
export const bundleHomeNewUsers = async () => {
const BUCKET_NAME = "my-project-firestore-data-bundles";
const admin = getAdmin();
const db = admin.firestore();
const bundle = db.bundle("home-users");
// Get 10 latest users.
const querySnapshot = await db
.collection("users")
.orderBy("createAt", "desc")
.limit(10)
.get();
const buffer = bundle.add("home-users-bundles-query", querySnapshot).build();
//Create tmp local file to upload
const bundledFilePath = `/tmp/bundle.txt`;
fs.writeFileSync(bundledFilePath, buffer);
//Upload bundle file to Storage
const destination = `firestore-data-bundles/home_users_bundles.txt`;
await firebase
.storage()
.bucket(BUCKET_NAME)
.upload(bundledFilePath, {
destination,
public: true,
metadata: {
cacheControl: `public, max-age=60, s-maxage=60`,
},
});
console.log(
`Uploaded to https://storage.googleapis.com/${BUCKET_NAME}/${destination}`
);
};
2. Here is generated txt file in GCS.
[https://storage.googleapis.com/my-project-firestore-data-bundles/home_users_bundles.txt]
139{"metadata":{"id":"home-users","createTime":{"seconds":"1646058787","nanos":2930000},"version":1,"totalDocuments":10,"totalBytes":"15264"}}354{"namedQuery":{"name":"home-users-bundles-query","bundledQuery":{"parent":"projects/my-project/databases/(default)/documents","structuredQuery":{"from":[{"collectionId":"users"}],"orderBy":[{"field":{"fieldPath":"createAt"},"direction":"DESCENDING"}],"limit":{"value":10}},"limitType":"FIRST"},"readTime":{"seconds":"1646058787","nanos":2930000}}}228{"documentMetadata":{"name":"projects/my-project/databases/(default)/documents/users/bTb06yIbG3eZK45PCCAOx1uhlhD2","readTime":{"seconds":"1646058787","nanos":2930000},"exists":true,"queries":["home-users-bundles-query"]}}
...
// Total 10 items
3. I've tried to load the bundle file in iOS project.
[MyFirestoreService.swift]
let urlString = "https://storage.googleapis.com/my-project-firestore-data-bundles/home_users_bundles.txt"
let url = URL(string: urlString)!
let bundle = try! String(contentsOf: url, encoding: .utf8)
let db = Firestore.firestore()
db.loadBundle(Data(bundle.utf8)) { progress, error in
print(progress?.totalDocuments) // 10
print(progress?.documentsLoaded) // 0
switch progress {
case .success:
db.getQuery(named: "home-users-bundles-query") { query in
if let query = query {
print("Ready to use named query.")
} else {
print("Failed to get named query.")
}
}
case .error:
print("error: \(error.debugDescription)")
/*
error: Optional(Error Domain=FIRFirestoreErrorDomain Code=2 "Loading bundle failed with unknown error" UserInfo={NSLocalizedDescription=Loading bundle failed with unknown error})
*/
default:
return
}
}
[Firebase SDK log]
8.12.1 - [Firebase/Firestore][I-FST000001] Failed to GetNextElement() from bundle with error 'values' is missing or is not an array
8.12.1 - [Firebase/Firestore][I-FST000001] Progress set to Error, but error_status() is ok()
[Dev environment]
XCode 13.2.1
FirebaseFirestore 8.12.1
Any ideas? I think this is kind of multi bytes or charset issue.