Skip to content

Firestore: Out of expect when document update SERVER_TIMESTAMP and an arbitrary value by field path #7215

@fishballLin

Description

@fishballLin

Environment details

  1. OS type and version:
    Both happened on Windows 7 and Ubuntu 18.04
  2. Python version:
    python 3.6
  3. google-cloud- version:
    firebase-admin 2.14.0
    google-api-core 1.7.0
    google-auth 1.6.2
    google-cloud-core 0.29.1
    google-cloud-firestore 0.31.0
    google-cloud-storage 1.13.2
    google-resumable-media 0.3.2
    googleapis-common-protos 1.5.5

Reference

The following case is modified by the firestore document update section example.

Steps to reproduce

  1. To illustrate this, consider a document with
>>> snapshot = document.get()
>>> snapshot.to_dict()
{
    'foo': {
        'bar': 'baz',
    },
    'other': True,
}

stored on the server.

  1. To set a field to the current time and another field to an arbitrary value(ex: "test"). We expect sending
>>> field_updates = {
...     'foo.now': firestore.SERVER_TIMESTAMP,
...     'foo.test': "test",
... }
>>> document.update(field_updates)

would update the value on the server to:

>>> snapshot = document.get()
>>> snapshot.to_dict()
{
    'foo': {
        'bar': 'baz',
        'now': datetime.datetime(2019, ...),
        'test': 'test'
    },
    'other': True,
}
  1. However, in the real case, the value on the server are:
>>> snapshot = document.get()
>>> snapshot.to_dict()
{
   'foo': {
       'now': datetime.datetime(2019, ...),
       'test': 'test'
   },
   'other': True,
}
  1. Apparently, the previous field 'foo.bar' disappear, but it doesn't match our expect.

Code example

Step 1: prepare the data
import firebase_admin
from firebase_admin import credentials, firestore

cred = credentials.Certificate('your-api-key.json')
firebase_admin.initialize_app(cred)

db = firestore.client()
document = db.collection('test').document()
document.set({
    "foo":{
        "bar": 'baz'
    },
    'other': True
})
snapshot = document.get()
print(snapshot.to_dict())

console:

{
    'foo': {
        'bar': 'baz',
    },
    'other': True,
}
Step 2: update the data
field_updates = {
    'foo.test': 'test',
    'foo.now': firestore.SERVER_TIMESTAMP,
}
document.update(field_updates)

snapshot = document.get()
print(snapshot.to_dict())

console:

{
    'foo': {
        'now': datetime.datetime(2019, ...),
        'test': 'test'
    },
    'other': True,
}
Expected output
{
    'foo': {
        'bar': 'baz',
        'now': datetime.datetime(2019, ...),
        'test': 'test'
    },
    'other': True,
}

Thank you.

Metadata

Metadata

Assignees

Labels

api: firestoreIssues related to the Firestore API.priority: p2Moderately-important priority. Fix may not be included in next release.status: acknowledgedtriaged for GAtype: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions