firebase-tools: Firestore security rule emulator - get and getAfter throwing an exception on non existant doc

[REQUIRED] Environment info

**firebase-tools:**7.16.1

**Platform:**Windows

[REQUIRED] Test case

Just write a rule using a get or getAfter on a non existant doc. For instance: allow update: if get(/databases/$(database)/documents/doc/doesnot/exist) == null;

[REQUIRED] Steps to reproduce

See above

[REQUIRED] Expected behavior

As per the doc get and getAfter should return null. this is what the online simulator does.

[REQUIRED] Actual behavior

An exception is thrown Service call error. Function: [get], Argument: [path_value { …}

About this issue

  • Original URL
  • State: open
  • Created 4 years ago
  • Reactions: 18
  • Comments: 27 (9 by maintainers)

Most upvoted comments

Any progress here?

@olivierkrener Thanks for reporting it! The fix for this is actually quite simple, but there’s a lot of organizational complexity surrounding it which will delay the release of the fix by around 1-2 months.

Thanks for reporting your experience VGerris, we’re aware of this issue (exists in production too) but we have no expected fix timeline.

How can a bug like this one be open for over two years? 😢 BUMP

Not sure if I’m supposed to link internal bugs here, but YOLO for posterity: b/152525307

@samtstern

Unfortunately I haven’t followed up with the current assignee for a while. I’m sorry about that. I’ll start annoying him to work on it. This is pretty egregious and needs to be fixed.

And that’s why I raised an issue for the ternary operator 😉

Started experiencing this on a very specific existsAfter call on only 2 of our 10+ dev environments. It throws an exception instead of returning as expected.

Anything we could do to debug this further? E.g. What could be affecting the affected envs, compared to the others?

Not with rules, you need to write server side logic because apparently Google doesn’t care about fixing the bug.

On Thu, May 4, 2023, 20:47 jellynoone @.***> wrote:

Just bumped into this. I’m trying to perform a transactional write, where two documents are created as a result and one of them is validated against another. Is there any other way to achieve this without bumping into this bug?

— Reply to this email directly, view it on GitHub https://github.com/firebase/firebase-tools/issues/2067#issuecomment-1535244382, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAGB3CMT2CULOEJQRQDITLLXEP2SRANCNFSM4LTYGNAQ . You are receiving this because you commented.Message ID: @.***>

Just bumped into this. I’m trying to perform a transactional write, where two documents are created as a result and one of them is validated against another. Is there any other way to achieve this without bumping into this bug?

Bump, this is still an issue. Any chance there’s been progress on this?

Okay! That’s great to hear. I’m sorry you’re experiencing this. Because the emulator mirrors the production experience, you may also encounter this in production. One workaround is to write a global function like this:

rules_version='2';
// Overload firestore-provided function at global scope.
function get(path) {
  // You'll have to wait for the ternary operator to be released in the emulators
  return exists(path) ? get(path) : null;
}
service cloud.firestore {
  // Your code here.
}

It’s not ideal because in production this may count as two data lookups instead of one, but it works. Also keep in mind that rules logic is ‘short-circuiting’ and that includes error handling. For example, `allow read: if get(/bad/path).boolean_field || true’ would return true even though the first branch is an error.

Edit: It probably doesn’t count as two rules lookups