Skip to content
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

Error when using "reference" type #10

Open
pbtaffi opened this issue Feb 10, 2022 · 1 comment
Open

Error when using "reference" type #10

pbtaffi opened this issue Feb 10, 2022 · 1 comment

Comments

@pbtaffi
Copy link

pbtaffi commented Feb 10, 2022

I have reference to objects from a foreign collection. How can I use Firestore Reference type for the ID.

Author{
    id: ID!
    name: String!
}

Book {
    id: ID!
    author: ID!
}

With the above, I get the above error which is expected:

ID cannot represent value: { _firestore: { _settings: [Object], _settingsFrozen: true, _serializer: [Serializer], _projectId: "taffi-stage", registeredListenersCount: 0, bulkWritersCount: 0, _backoffSettings: [Object], _clientPool: [ClientPool] }, _path: { segments: [Array] }, _converter: { toFirestore: [function toFirestore], fromFirestore: [function fromFirestore] } }

Is there a way for me to use Firestore "Reference Type" as the ID to refer to a document from foreign collection ?

Thank you.

@swantzter
Copy link
Owner

Hi, not currently.

There are some decisions that would have to be made to support this. Since the DocumentReference instance contains the full path to the document it references, not just the ID, the behaviour when you give it to a DataSource initialised with a different collection would have to be defined.

Given the following setup:

export interface AuthorDoc {
  readonly id: string
  readonly collection: 'authors'
  name: string
}

export interface PostsDoc {
  readonly id: string
  readonly collection: 'posts'
  title: string
  authorRef: DocumentReference
}

export class AuthorDataSource extends FirestoreDataStore<AuthourDoc, ApolloContext> {}
export class PostsDataSource extends FirestoreDataStore<PostsDoc, ApolloContext> {}

const authorsDS = new AuthorDataSource(firestore.collection('authors'))
const postsDS = new PostsDataSource(firestore.collection('posts'))

The "correct" behaviour would probably look something like this:

const post = await postsDS.findOne('abc123')
const author = await authorsDS.findOne(post.authorRef)

However, what happens if we do

const post = await postsDS.findOne('abc123')
const author = await postsDS.findOne(post.authorRef)

does it

  1. throw an error because the DocumentRef#collection of authorRef !== 'posts' which is the collection the postsDS is initialised with?
  2. Does it ignore the collection and just attempt to load a post with the id in DocumentReference#id? (this would probably cause havoc on the type system, or if you have two collections with the same type of documents it would cause a security issue)
  3. Load the specified document but in the wrong datasource (definitely no, this would cause havoc on the type system)

And then, if it does (1), should it do so in a "deep" fashion?
Sure this library currently encourages only operating on top-level collections, but what if you have sub-collections and you have one data source set up to point at /collection1/doc1/collection1a and one to point at /collection2/doc1/collection1a. if you try to load a reference pointing to /dollection1/doc1/collection1a/doc2a from the datasource initialised with /collection2/doc1/collection1a it would load fine if you only checked the first level of collection depth (since collection1a is the same for both) which could mean you're loading the wrong document and creating a security issue.

My personal solution at the moment is storing authorId as a string and loading based on that - as a workaround for you until this is implemented you could do await authorsDS.findOne(post.authorRef.id)

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

No branches or pull requests

2 participants