netskink
netskink

Reputation: 4539

How to create an entry in google cloud firestore in python for a timestamp

I have a python 3.7 based cloud function. I have a value for seconds since epoch. I can add a series of entries for a document as string, integer etc. I can not add a timestamp though.

Here is a simple code snippet.

db = firestore.Client(project=project_id)

# the event dictionary already has some values in it.  Add a timestamp.
#

# This is a reference to javascript api.  Oddly enough this page does not have
# python listed.
# https://firebase.google.com/docs/reference/js/firebase.firestore.Timestamp
#
# This will add a timestamp as a string value.
event['mqtt_timestamp_rfc3339'] = mqtt_timestamp_rfc3339 # add the timestamp as a string

# this adds a the value as a number of seconds since epoch
event['timestamp_secs'] = mqtt_timestamp  # add the timestamp as timestamp class

# This fails.
# firestore.types.Value.timestamp_value(seconds=mqtt_timestamp.timestamp())  

# This actually updates the collection
doc_ref = db.collection(u'sensor-data').add(event)

The only thing I have seen so far from the example code is adding a timestamp which appears to be server time. In this case, I have a device which relays its info to a second device which in turn updates to pub/sub. I don't really care about when the cloud function is called. I want to know when the first device generated the event which could be considerable minutes before.

Upvotes: 4

Views: 9974

Answers (3)

Csaba Toth
Csaba Toth

Reputation: 10719

Firestore stores timestamps in a typed manner and it's not an integer like JavaScript's millisecond or a UNIX epoch. Like so: enter image description here

This means that whichever language's package you use should take care of this (meaning it supply the expected date/time data to/from Firebase). For example in case of a Kotlin Android application my RemoteAssetMapper.kt has a fun mapDateToTimestamp(date: Date): Timestamp function which converts java.util.Date to com.google.firebase.Timestamp.

In your case Python has a package google-cloud-firestore I assume you are using in your cloud function. I haven't used Firestore with Python yet, but from the example codes it looks like that this Python package should be able to take regular Python datetime object and convert that and supply the required data to Firestore:

data = {
    u'stringExample': u'Hello, World!',
    u'booleanExample': True,
    u'numberExample': 3.14159265,
    u'dateExample': datetime.datetime.now(),
    u'arrayExample': [5, True, u'hello'],
    u'nullExample': None,
    u'objectExample': {
        u'a': 5,
        u'b': True
    }
}

db.collection(u'data').document(u'one').set(data)

Now in your case you may receive timestamps from IoT edge devices through MQTT protocol which sounds like to be possibly a UNIX epoch time. I'd start to look at datetime.fromtimestamp (https://docs.python.org/2/library/datetime.html#datetime.datetime.fromtimestamp) or datetime.utcfromtimestamp. You need to deal with time zones! Then once you have the Python datetime, theoretically - by the documentation - you can supply that as the Firestore timestamp, the pip package will take care of the rest of the conversion.

Upvotes: 3

netskink
netskink

Reputation: 4539

This method works for a cloud function using python 3.7.

doit():

    # stuff snipped for brevity

    # unpack timestamp as string from buffer
    mqtt_timestamp_str = mqtt_timestamp_bytes.decode("utf-8")
    # generate timestamp from string
    mqtt_timestamp = datetime.fromisoformat(mqtt_timestamp_str)
    # create as RFC339 string
    mqtt_timestamp_rfc3339 = rfc3339(mqtt_timestamp, utc=True, use_system_timezone=False)

    # stuff snipped. event is a dictionary with stuff to put in firebase

    # add the timestamp as RFC339 String
    event['mqtt_timestamp_rfc3339'] = mqtt_timestamp_rfc3339 
    event['timestamp'] = mqtt_timestamp  

    # update firebase
    doc_ref = db.collection(u'sensor-data').add(event)
    

Upvotes: 2

Haris ramzan
Haris ramzan

Reputation: 93

Using firebase timestamp function but it will save the server time regionwise..

client.collection('sensor-data').document('mydoc').set({
    'mytime':firestore.SERVER_TIMESTAMP
})

Upvotes: 4

Related Questions