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

Unexpected onCreate behavior after changing collection path and hot reload #2533

Closed
katopz opened this issue Aug 7, 2020 · 1 comment · Fixed by #3557
Closed

Unexpected onCreate behavior after changing collection path and hot reload #2533

katopz opened this issue Aug 7, 2020 · 1 comment · Fixed by #3557

Comments

@katopz
Copy link

katopz commented Aug 7, 2020

[REQUIRED] Environment info

firebase-tools:
8.7.0

"firebase-admin": "^9.0.0",
"firebase-functions": "^3.9.0",

Platform:
macOS 10.15.5

[REQUIRED] Test case

import * as functions from 'firebase-functions'
import * as firebase from 'firebase-admin'

// Admin service account key
const serviceAccount = require('../firebase-admin.staging.key.json')
firebase.initializeApp({
  credential: firebase.credential.cert(serviceAccount)
})

export const watchCreate1 = functions.firestore
  .document('{a}/{b}')
  .onCreate((snap, context) => console.log('watchCreate1:', context.params))

export const watchCreate2 = functions.firestore
  .document('{a}/{b}/{c}/{d}')
  .onCreate((snap, context) => console.log('watchCreate2:', context.params))

console.log('Add /foo/bar')
// tslint:disable-next-line: no-floating-promises
firebase
  .firestore()
  .collection('foo')
  .doc('bar')
  .set({ bar: 'bar' })

[REQUIRED] Steps to reproduce

  1. Run above code
  2. Get output
    watchCreate1: { a: 'foo', b: 'bar' }
    
  3. Clear all data via http://localhost:4006/firestore
  4. Change watchCreate1 function to...
    export const watchCreate1 = functions.firestore
      .document('{a}/{b}/{c}/{d}')
      .onCreate((snap, context) => console.log('watchCreate1:', context.params))
    Then save file to trigger nodemon to recompile the code.
  5. Get output
    watchCreate1: { a: 'foo', b: 'bar', c: undefined, d: undefined }
    

[REQUIRED] Expected behavior

Judge from second attempt, The first run should return...

watchCreate1: { a: 'foo', b: 'bar' }
watchCreate2: { a: 'foo', b: 'bar', c: undefined, d: undefined }

[REQUIRED] Actual behavior

watchCreate1: { a: 'foo', b: 'bar' }

What I'm trying to do

I'm trying to watch all update in one function but it seem to do able only after changing code and hot reload. e.g.

export const watchCreate = functions.firestore
  .document('{a}/{b}/{c}/{d}/{e}/{f}/{g}/{h}/{i}/{j}/{k}/{l}/{m}/{n}/{o}/{p}/{q}/{r}/{s}/{t}/{u}/{v}/{w}/{x}/{y}/{z}')
  .onCreate((snap, context) => console.log('watchCreate1:', context.params))

Didn't to work at first run but if I change the code and do hot reload it will work as expect.
FYI : I expect { a: 'foo', b: 'bar', c: undefined, d: undefined, ... }
But whenever I restart emu, I will got not thing because {a}/.../{z} didn't match foo/bar.

I know this is sound weird and confuse, I lost an hour to figure this strange behavior anyway.
BTW, I wouldn't know what collection name will be add at root by user, so I've to dynamically watch it as {a}.

@samtstern
Copy link
Contributor

@katopz thanks for the descriptive issue. I think this is actually working as intended, although it's definitely confusing! I think the hot reload is failing to notice the updated trigger definition, which is a bug. However you can't really do what you're trying to do:

If you have this trigger:

functions.firestore.document('{a}/{b}/{c}/{d}').onCreate({ ... });

A write to /foo/bar does NOT match that description. {c} and {d} must be path segments with length >=0 to match.

That said if you're really set on this, you can do:

// Match all writes to top level collections like /foo/bar
functions.firestore.document('{a}/{b}').onCreate({ ... });

// Match all writes to second level collections like /foo/bar/sub/doc
functions.firestore.document('{a}/{b}/{c}/{d}').onCreate({ ... });

// Match all writes to third level collections like /foo/bar/sub/doc/sub/doc
functions.firestore.document('{a}/{b}/{c}/{d}/{e}/{f}').onCreate({ ... });
// etc

@samtstern samtstern self-assigned this Aug 10, 2020
@samtstern samtstern added this to the v8.0.0 milestone Jul 7, 2021
@samtstern samtstern added this to To do in Fixit - H2 2021 via automation Jul 7, 2021
@samtstern samtstern removed this from the v8.0.0 milestone Jul 7, 2021
Fixit - H2 2021 automation moved this from To do to Done Jul 8, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Development

Successfully merging a pull request may close this issue.

2 participants