Skip to content

Exporting all API types #123

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

Merged
merged 2 commits into from
Feb 1, 2018
Merged

Exporting all API types #123

merged 2 commits into from
Feb 1, 2018

Conversation

schmidt-sebastian
Copy link
Contributor

@schmidt-sebastian schmidt-sebastian commented Feb 1, 2018

This PR exports all public types to allow end user to use them in their code directly, e.g. for instanceof checks.

b/72759064
https://stackoverflow.com/questions/48552183/how-to-get-firestore-documentreference-class

@googlebot googlebot added the cla: yes This human has signed the Contributor License Agreement. label Feb 1, 2018
Copy link

@hiranya911 hiranya911 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with a couple of nits

src/index.js Outdated
@@ -1117,7 +1117,8 @@ validate = require('./validate')({
DocumentReference: reference.validateDocumentReference,
ResourcePath: ResourcePath.validateResourcePath,
});
WriteBatch = require('./write-batch')(Firestore, DocumentReference).WriteBatch;
let batch = require('./write-batch')(Firestore, DocumentReference);

This comment was marked as spam.

This comment was marked as spam.

* @type {Constructor}
*/
module.exports.GeoPoint = GeoPoint;
module.exports.FieldPath = FieldPath;

This comment was marked as spam.

This comment was marked as spam.

@codecov
Copy link

codecov bot commented Feb 1, 2018

Codecov Report

Merging #123 into master will not change coverage.
The diff coverage is 100%.

Impacted file tree graph

@@          Coverage Diff          @@
##           master   #123   +/-   ##
=====================================
  Coverage     100%   100%           
=====================================
  Files          12     12           
  Lines        1648   1661   +13     
=====================================
+ Hits         1648   1661   +13
Impacted Files Coverage Δ
src/reference.js 100% <ø> (ø) ⬆️
src/index.js 100% <100%> (ø) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update a16c3eb...93cbd40. Read the comment docs.

@schmidt-sebastian schmidt-sebastian merged commit 51e076e into master Feb 1, 2018
@ghost ghost removed the cla: yes This human has signed the Contributor License Agreement. label Feb 1, 2018
@willhlaw
Copy link

willhlaw commented Feb 6, 2018

@schmidt-sebastian, thanks for the quick response on this! I saw this from the SO question. Can ResourcePath also be exposed? It will help in constructing DocumentReference fields for testing purposes.

@schmidt-sebastian
Copy link
Contributor Author

ResourcePath is internal only and not intended to be part of the public API. We may change, rename or remove it at any point and hence exporting it is not an option for us at this point.

Note that you might find this helper function useful for testing: https://github.com/googleapis/nodejs-firestore/blob/master/src/index.js#L350
This function also internal and private, but the Firebase Functions SDK uses it and so it is a little less likely to go away. Note that despite this endorsement, we won't provide any guarantee for its functionality.

@willhlaw
Copy link

willhlaw commented Feb 7, 2018

@schmidt-sebastian, thanks. I took a quick look into that link, which led me to trying out require('firebase-admin').firestore.DocumentSnapshot and its Builder. The knowledge may come in handy down the road. It wasn't exactly what I was looking for.

For saving Firestore documents and later restoring them to the same or another Firestore project, one would need to maintain field type integrity. For reference / DocumentReference types, how would you go about doing it?

The approach I took in the latest 1.2.1 version of https://www.npmjs.com/package/firestore-backup-restore was to drop _firestore field and just store _referencePath. To reconstruct when restoring from disk to Firestore, the _referencePath.segments are picked out and require('firebase-admin').initializeApp().firestore().collection(collectionName).doc(documentName).collection(subCollectionName).doc(subDocumentName)._referencePath is then used as the field value when seting to Firestore. My gut, which is sick from typing and then reading all that, tells me there is probably a better way.

@schmidt-sebastian
Copy link
Contributor Author

I will talk to the rest of my team if we can provide better support for tools like yours. While we don't want end users to rely on the internals of our API, it makes sense for tools build on top of our clients.

In the meantime, I have some suggestions for you: For one, you don't have to manually walk the hierarchy chain. You can directly pass ReferencePath.formattedName to firestore.doc() (doc() takes 'a/b/c/d' paths).

Another option would be to call the snapshot_() function I mentioned and don't provide any data. That will get you a DocumentSnapshot whose DocumentReference you could use in your SDK.

In general, the fewer private methods you end us using, the happier you will end up being (even if you have to go through more hoops).

@stephenplusplus stephenplusplus deleted the mrschmidt-exports branch February 7, 2018 15:35
@willhlaw
Copy link

willhlaw commented Feb 8, 2018

It looks to me like the myDocumentReferenceField._referencePath returned from the SDK does not contain the formattedName. I do see it under myDocumentReferenceField._firestore._referencePath, but it of course stops at the database name (i.e. "projects/projectName/databases/(default)").

So I forgot that firestore.doc() could take a/b/c/d paths. Thanks! So rather than the awkward walk I mentioned above, I could just do require('firebase-admin').initializeApp().firestore().doc(_referencePath.segments.join('/')).

Lastly, I finally was able to find the snapshot_ constructor. Although, it appears it cannot be called without data and requires first param documentOrName to contain a name field, which then needs to be a valid absolute ResourcePath string (which is what formattedName is I think). A DocumentReference can be created with the following:
new (require('firebase-admin').firestore.Firestore)().snapshot_('projects/projectId/databases/(default)/documents/collectionName/documentName')._ref

To conclude, I think storing the _referencePath as JSON to disk and then reconstructing the object before seting to Firestore can be done using either method. It's really the projectId that needs to change if cloning data from one Firestore to another, but the insight from this exploration may be useful when implementing a transformation function (to allow data hierarchy migrations such as moving a subcollection up to a top level collection or vice versa).

Thanks @stephenplusplus for all the info. It doesn't seem necessary anymore to expose ResourcePath.

@schmidt-sebastian
Copy link
Contributor Author

You might find these tests useful if you need help with the private snapshot_ API: https://github.com/googleapis/nodejs-firestore/blob/master/test/index.js#L645

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants