-
Notifications
You must be signed in to change notification settings - Fork 374
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(fs): preferRest app option for Firestore #1901
Conversation
f0ab63e
to
b07ac82
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you @alexander-fenster !
This is great! We need an internal API proposal for changes to the public API before we can merge this PR. I also left a comment below on making the config an App option.
src/app/core.ts
Outdated
* HTTP/1.1 REST transport if possible. Note that gRPC will still be | ||
* used for calls that need bi-directional streaming. | ||
*/ | ||
preferRest?: boolean; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not entirely sure about making this an app option... is the idea to reuse the same config for other gRPC libraries in the future?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was just my first thought to pass it the same way as other options - alternatively, we can make it a second parameter to the Firestore
client, or enable this via an environment variable. What would you suggest? I don't know this codebase :) I'll follow up internally to figure out the API proposal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have been using the admin SDK for a couple of years and have recently changed over to using import which uses getFirestore(appInstance)
which would only work if either an ENV variable was set, or http was set in the app instance (or add more arguments to getFirestore)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are actually thinking of adding the second parameter to getFirestore
, looks like the cleanest solution. I'll get back here after we discuss internally.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would have expected that you'd set it the same way you'd configure the ignoreUndefinedProperties
Firestore setting (given how it's implemented in the @google-cloud/firestore
library)
So:
getFirestore().settings({
preferRest: true
})
But if more libraries will eventually support REST over only GRPC, then I'd expect to be in the AppOptions
, like:
initializeApp({
preferRest: true,
})
Maybe both should be possible if you want REST only for Firestore but not other libraries.
But if you want REST for ALL libraries, then it would be nice if you could define it via the AppOptions
.
Any progress on this? We're so close! |
Thank you @GriffinJohnston ! We have started the internal API review process for this. |
Typically how long does the API review process take? 1 month? 3 months? 12 months? Excited for this functionality. Thank you! |
The review is completed, we decided we'll take a slightly different approach (adding |
By the way firebase-auth's new blocking function feature has a timeout of 7 seconds, making it tough to use without this feature. |
Glad I didn't start using that then, you can't always init the admin sdk and load from firestore within 7 seconds 🤦 |
Any new progress on this? this feature would be really useful for us as we have seen significant speedup when using preferRest on the backend, but need to use it with the admin SDK. If this option won't land soon, any suggestions for using the admin SDK on a serverless backend (Firebase cloud functions) but still getting the improved preferRest behavior? |
+1 to keeping a fire lit under this project. I think Googlers maybe don't understand how big a deal this is. I talk to quite a few devs using Firestore and the only complaint every single one of them mentions is this exact cold start issue. |
b07ac82
to
44d2779
Compare
@lahirumaramba PTAL. I replaced the implementation according to the design as we discussed. |
…min-node into preferRest
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you @alexander-fenster ! LGTM!
src/firestore/index.ts
Outdated
* | ||
* @param settings - Settings object to be passed to the constructor. | ||
* | ||
* @returns The `Firestore` service associated with the provided app. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be @returns The
Firestore service associated with the provided app and settings
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@alexander-fenster Let's get TW review on the reference docs. Thanks!
*/ | ||
export interface FirestoreSettings { | ||
/** | ||
* Use HTTP/1.1 REST transport where possible. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It may be worth clarifying the behavior of this setting.
preferRest
will force the use of HTTP/1.1 REST transport until an operation requires GRPC. When an operation requires GRPC, this Firestore client will load dependent GRPC libraries and then use GRPC transport for all communication from that point forward. Currently the only operation that requires GRPC is creating a snapshot listener using onSnapshot(...)
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
@alexander-fenster With the new function e.g., code like this will fail with an initializeFirestore(getApp(), {
preferRest: true,
});
getFirestore().settings({
timestampsInSnapshots: true,
ignoreUndefinedProperties: true,
}); However, it's not possible to do the following: initializeFirestore(getApp(), {
preferRest: true,
timestampsInSnapshots: true,
ignoreUndefinedProperties: true,
}); as only However, this seems to work: getFirestore().settings({
timestampsInSnapshots: true,
ignoreUndefinedProperties: true,
preferRest: true,
}); |
I'm currently using a simple setup like this:
I then require db from individual functions. This setup is producing the following error:
Am I doing something obviously wrong? How do you suggest using this new |
Hi @GriffinJohnston, This error only occurs if you are trying to call Folks, for any issues you are encountering with this feature please create a new issue. That way the team can easily track and address them separately. Thanks again for using this feature and giving us your feedback! We appreciate it!! |
@lahirumaramba Thanks for getting back to me - sorry for turning this into a support thread :) I haven't been able to get
I'll open a new issue if I have futher questions, but could you confirm that using Thanks again for getting this out the door. |
According to the
@alexander-fenster is currently looking into this. @GriffinJohnston if you can reproduce the issue with |
Hey all const admin = require("firebase-admin");
const { getFirestore } = require("firebase-admin/firestore");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
storageBucket: SECRETS.storage.bucket,
});
getFirestore().settings({
preferRest: true,
});
module.exports = admin;
// then outside this file
const users = await admin.firestore().collection("Users").get(); |
Hi @omar-dev-amrk, below is the correct way to use the API:
There was a known caching issue that we have discussed above that was fixed in #2040. We will include the fix in this week's release. Thanks! |
Hey @lahirumaramba Can I use it in production now, or would it be safer to wait for the caching issue fix? |
Hey @omar-dev-amrk the fix is now included in the v11.5.0 release. Feel free to use it in production. If you encounter any problems, please open a new issue. Folks, if you get a chance to try out this feature let us know what you think. Thanks! |
Hello @lahirumaramba After the deployment finished, I kept getting errors like:
and
What's weird was that it works fine after a certain amount of errors, then goes back to erring again. What can we do in the meantime? |
@omar-dev-amrk Since Cloud Firestore support is provided by the @google-cloud/firestore library, I would suggest you to report this directly on the nodejs-firestore GitHub repo. Thanks! |
Just FYI, I filed googleapis/gax-nodejs#1423 about "callback is not a function" error. It looks like it tries to fail the request for whatever reason but fails to call |
What is the recommended way to use preferRest -- for my code structure, that looks like the following: index.ts
example.ts
Doing the following on index.ts is enough?
|
Your approach looks good, it's aligned with this comment: #1901 (comment). Are you having trouble?
|
When I turn on
Is this something I need to worry about @MarkDuckworth ? Maybe something to do with: googleapis/nodejs-firestore#1811 |
@MarkDuckworth My E2E tests using playwright and firebase functions also fail in CI Github Actions |
It may be inappropriate to write here, but I took a simple measurement of performance
|
const middleware = async (req, res) => {
|
My package version is 11.8.0
|
This seems to be the recommended technique: firebase/firebase-admin-node#1901 (comment)
Any progress on this #1901 (comment) ? |
@Psycarlo, please open an issue and fill in the required fields so that we have enough context to help you resolve this. Thanks! |
Fixes #1879 by providing a way to pass
preferRest
to theFirestore
constructor. This is coming from the solution we provided in https://issuetracker.google.com/issues/158014637. ThepreferRest
option might become default in@google-cloud/firestore
later (possibly after the next major), but for now, we'd better keep this behind a flag, so the customers asked for a way to pass this flag fromfirebase-admin
.