-
Notifications
You must be signed in to change notification settings - Fork 930
Enable firestore sdk to talk to emulator #1007
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
Conversation
packages/testing/src/api/index.ts
Outdated
import * as admin from 'firebase-admin'; | ||
import request from 'request-promise'; | ||
import * as fs from 'fs'; | ||
import { FirebaseApp } from '@firebase/app-types'; | ||
import * as util from '@firebase/util'; |
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.
is there a better way to import these?
@@ -179,7 +182,13 @@ export class FirebaseCredentialsProvider implements CredentialsProvider { | |||
const initialUserCounter = this.userCounter; | |||
const forceRefresh = this.forceRefresh; | |||
this.forceRefresh = false; | |||
return (this.app as _FirebaseApp).INTERNAL.getToken(forceRefresh).then( | |||
var token: Promise<FirebaseAuthTokenData>; |
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.
Do we have to modify the Firestore SDK in order to get this to work? I'd prefer not to introduce this tokenOverride
value.
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.
AFAICT, we'd have to change app-types
to export FirebaseAppImpl
or to move INTERNAL
into FirebaseApp
to give visibility to the testing package. If that's the only way to do this, I'd rather modify the firestore
package than app
package
packages/testing/src/api/index.ts
Outdated
tokenOverride: fakeToken | ||
}, | ||
'app-' + new Date().getTime() + "-" + Math.random() | ||
); |
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.
Can we initialize the app here, then immediately hijack the INTERNAL.getToken
function?
I’m soooo happy to see this PR! You can’t even imagine! |
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.
run npm test
and make sure the linter likes your code. I think it made me change anything that wasn't mutable into a const
declaration (instead of var
).
packages/testing/src/api/index.ts
Outdated
} | ||
if (typeof options.auth != 'object') { | ||
throw new Error('auth must be an object'); | ||
} |
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.
If you want, you could declare the type for options
(instead of leaving it as any
) and let the compiler construct these assertions for you.
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
packages/testing/src/api/index.ts
Outdated
}, | ||
'app-' + new Date().getTime() + '-' + Math.random() | ||
); | ||
(app as any).INTERNAL.getToken = () => |
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.
can you add a comment here explaining that this INTERNAL.getToken
hijack is to inject the predefined authorization headers into the app (thus bypassing FirebaseAuth)?
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
Also please don't submit this until at least one of the other reviewers LGTMs it. |
packages/testing/src/api/index.ts
Outdated
if (!('databaseName' in options)) { | ||
throw new Error('databaseName not specified'); | ||
} | ||
export type TestAppOptions = { |
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 suggest to make this an interface or to just inline it and use two arguments in initializeTestApp
.
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.
Almost :) But it looks fine the way it is.
packages/testing/src/api/index.ts
Outdated
@@ -36,6 +39,10 @@ export function apps(): (admin.app.App | null)[] { | |||
return admin.apps; | |||
} | |||
|
|||
export function firestoreApps(): (FirebaseApp | null)[] { |
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.
The distinction between Admin App
, Test App
and Firestore Test App
is not very clear. Would it be possible to add an argument to initializeTestApp
that allows us to turn on Firestore support?
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'm combining initializeTestApp and initializeFirestoreTestApp. though the backend support won't land until next week.
packages/testing/src/api/index.ts
Outdated
} | ||
export type TestAppOptions = { | ||
databaseName: string; | ||
auth: Object; |
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.
Note that Object will only allow empty objects. You should use object
.
https://blog.mariusschulz.com/2017/02/24/typescript-2-2-the-object-type
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.
good catch
packages/testing/src/api/index.ts
Outdated
].join('.'); | ||
const app = firebase.initializeApp( | ||
{ projectId: options.projectId }, | ||
'app-' + new Date().getTime() + '-' + Math.random() |
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.
You can make this a little more intuitive if you add a local variable that will help let users know that this is the appName
.
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
@@ -108,13 +126,27 @@ describe('Testing Module Tests', function() { | |||
).to.throw(/Could not find file/); | |||
}); | |||
|
|||
it('apps() returns all created apps', async function() { | |||
it('apps() returns all apps created except by initializeFirestoreTestApp', async function() { |
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 behavior is strange and unexpected.
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.
cleaned it up
packages/testing/src/api/index.ts
Outdated
appOptions = { | ||
databaseURL: DBURL + '?ns=' + options.databaseName | ||
}; | ||
} else if ('projectId' in options) { |
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.
Is there a reason to not support both projectId
and databseURL
? This code might be a little cleaner if you supported both, even if the interface doesn't allow for it.
packages/testing/src/api/index.ts
Outdated
if (!('databaseName' in options)) { | ||
throw new Error('databaseName not specified'); | ||
} | ||
export type TestAppOptions = { |
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.
Almost :) But it looks fine the way it is.
packages/testing/index.ts
Outdated
@@ -26,5 +26,6 @@ export { | |||
assertSucceeds, | |||
initializeAdminApp, | |||
initializeTestApp, | |||
initializeFirestoreTestApp, |
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.
You need to remove this to get the CI to pass.
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
…the testing sdk to no longer work with old versions of the RTDB emulator
packages/testing/package.json
Outdated
@@ -1,6 +1,6 @@ | |||
{ | |||
"name": "@firebase/testing", | |||
"version": "0.1.0", | |||
"version": "1.0.0", |
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 don't need to do this, even though it is a breaking change major 0
s allow for breaking changes between other versions also. Additionally, I update this at publish time so no need to edit.
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
* Add @davideast as a CODEOWNER (#996) * Embed metadata directly into the RPC call (#979) * Embed metadata directly into the RPC call * [AUTOMATED]: Prettier Code Styling * Use ...args * [AUTOMATED]: Prettier Code Styling * Minimize diff * Add the OAuth assertion back in * Added missing type for optional database url. (#1001) * RxFire Realtime Database (#997) * initial database code * test setup * database tests * auditTrail and database tests * [AUTOMATED]: Prettier Code Styling * [AUTOMATED]: License Headers * Josh's comments. Database docs * [AUTOMATED]: Prettier Code Styling * Firestore docs * auth docs * declaration fixes * switch to peerDeps * [AUTOMATED]: Prettier Code Styling * test config * Expose array transforms and array contains queries. (#1004) Also remove test code that was combining multiple array contains queries since those were disallowed in 04c9c3a. * Move fieldFilter (free function) to Filter.create() (#988) This is a refactoring to unify filter creation across platforms. * Enable firestore sdk to talk to emulator (#1007) * Enable firestore sdk to talk to emulator * [AUTOMATED]: Prettier Code Styling * Revert firestore sdk changes * [AUTOMATED]: Prettier Code Styling * Revert credentials.ts * Cleanup * [AUTOMATED]: Prettier Code Styling * Set webSafe=false * Combine initializeTestApp and initializeFirestoreTestApp * [AUTOMATED]: Prettier Code Styling * Cleanup * [AUTOMATED]: Prettier Code Styling * Update major version since this is a breaking change that will cause the testing sdk to no longer work with old versions of the RTDB emulator * Completely remove admin sdk * Change version back to 0.1.0 * Setting GarbageSource in SyncEngine's constructor (#1010) * b/72533250: Fix issue with limbo resolutions triggering incorrect manufactured deletes. (#1014) This fixes an issue occurring when a limbo target receives a documentUpdate, then a global snapshot, and then a CURRENT. Because there was a global snapshot before the CURRENT, WatchChangeAggregator has no pending document updates and calls SyncEngine.targetContainsDocument() to see if we previously got any document from the backend for the target. See: https://github.com/firebase/firebase-js-sdk/blob/6905339235ad801291edc696dd75a08e80647f5b/packages/firestore/src/remote/watch_change.ts#L422 Prior to this change, targetContainsDocument() returned false because it relies on our Views to track the contents of the target, and we don't have Views for limbo targets. Thus WatchChangeAggregator incorrectly manufactures a NoDocument document update which deletes data from our cache. The fix is to have SyncEngine track the fact that we did indeed get a document for the limbo resolution and return true from targetContainsDocument(). * Updating yarn.lock * Add @firebase/util as a dep of @firebase/testing * Allow remote updates from watch to heal a cache with synthesized deletes in it (#1015) * Write a spec test for the busted cache * Modify spec test to demonstrate deletedDoc issue. (#1017) * Allow updates for targets where the document is modified * Fix getRemoteKeysForTarget() method name in comment. (#1020) While porting I noticed this was slightly wrong. targetContainsDocument() is the method in WatchChangeAggregator. The SyncEngine method I meant to reference is getRemoteKeysForTarget(). * Making sure we don't export 'experimental' (#1023) * Add a schema migration that drops the query cache (#1019) * Add a schema migration that drops the query cache This is a force fix for potential existence filter mismatches caused by firebase/firebase-ios-sdk#1548 The essential problem is that when resuming a query, the server is allowed to forget deletes. If the number of incorrectly synthesized deletes matches the number of server-forgotten deletes then the existence filter can give a false positive, preventing the cache from self healing. Dropping the query cache clears any client-side resume token which prevents a false positive existence filter mismatch. Note that the remote document cache and mutation queues are unaffected so any cached documents that do exist will still work while offline. * Implement review feedback * Add a release note for the fix to #1548 (#1024) * Ensure that we create an empty TargetGlobal row. (#1029) Ensure the v3 migration unconditionally creates the TargetGlobal row. Remove the no-longer-necessary v2 schema migration. * Remove unnecessary `any` (#1030) * Fix an errant any usage * [AUTOMATED]: Prettier Code Styling * Publish [email protected] * Unify local.QueryData with the other platforms (#1027) This makes it line up with it's own docs, and also the other platforms. * Fix to #1027 to allow SnapshotVersion == 0 (#1033) * Add iat to fake access token payload (#1022) * Add iat to fake access token payload * [AUTOMATED]: Prettier Code Styling * Simpler tests * [AUTOMATED]: Prettier Code Styling * Do not clobber iat * catch server error RESET_PASSWORD_EXCEED_LIMIT (#1037) * Merging Master into Multi-Tab (#1038)
This change enables the testing sdk to talk to the firestore emulator. This is based off of https://docs.google.com/document/d/1dWAVm8-jK_JLsCOx4uZBj2MN_6auc7ood-0llWoojs8/edit?ts=5b47bec0#heading=h.sm63cr1eg2l2