GodotNuts / GodotFirebase

Implementations of Firebase for Godot using GDScript
MIT License
532 stars 76 forks source link

How to store a timestamp to firestore? [QUESTION] #143

Closed Zarasan closed 3 years ago

Zarasan commented 3 years ago

How do I store a timestamp to Firestore.

I am getting current time with OS.get_datetime(), but I don't know how to add it to firestore as a timestamp

BearDooks commented 3 years ago

@Zarasan if you are storing this data in a variable you should be able to add it to a document with ease.

See: https://github.com/GodotNuts/GodotFirebase/wiki/Firestore#add-a-document

an example would be something like

var my_timestamp = OS.get_datetime()
var add_task : FirestoreTask = firestore_collection.add("DOCUMENT_ID", {'name': Document 1', 'Timestamp': 'my_timestamp'})
var document : FirestoreDocument = yield(add_task, "task_finished")

This should hopefully make a new document and on of the fields inside of it will be the timestamp you took.

WolfgangSenff commented 3 years ago

@Zarasan - since we haven't heard back from you yet, I'm going to go ahead and close this. If it's still borked, let us know!

Zarasan commented 3 years ago

Hello, sorry for the delay in writing back.

When I stored the timestamp it stored it like a map and not like timestamp. After a bit of researching I found how Firestore stores it.

Here is my fix for sending timestamp to firestore.

# Pass a dictionary { 'key' : 'value' } to format it in a APIs usable .fields 
static func dict2fields(dict : Dictionary) -> Dictionary:
    var fields : Dictionary = {}
    print(dict)
    var var_type : String = ""
    for field in dict.keys():
        var field_value = dict[field]
        if typeof(dict[field]) == TYPE_DICTIONARY:
            if dict[field].has_all(['year','month','day','hour','minute','second']):
                var_type = 'timestampValue'
                field_value = '%04d-%02d-%02dT%02d:%02d:%02d.00Z' % [int(dict[field].year), int(dict[field].month), int(dict[field].day), int(dict[field].hour), int(dict[field].minute), int(dict[field].second)]
        else:
            match typeof(dict[field]):
                TYPE_NIL: var_type = "nullValue"
                TYPE_BOOL: var_type = "booleanValue"
                TYPE_INT: var_type = "integerValue"
                TYPE_REAL: var_type = "doubleValue"
                TYPE_STRING: var_type = "stringValue"
                TYPE_DICTIONARY:
                    var_type = "mapValue"
                    field_value = dict2fields(field_value)
                TYPE_ARRAY:
                    var_type = "arrayValue"
                    field_value = {"values": array2fields(field_value)}
        fields[field] = { var_type : field_value }
    return {'fields' : fields}
fenix-hub commented 3 years ago

Could be better formatted like this and implemented:

match typeof(field_value):
    TYPE_NIL: var_type = "nullValue"
    TYPE_BOOL: var_type = "booleanValue"
    TYPE_INT: var_type = "integerValue"
    TYPE_REAL: var_type = "doubleValue"
    TYPE_STRING: var_type = "stringValue"
    TYPE_DICTIONARY:
    if field_value.has_all(['year','month','day','hour','minute','second']):
        var_type = "timestampValue"
        field_value = dict2timestamp(field_value)
    else:
        var_type = "mapValue"
        field_value = dict2fields(field_value)
    TYPE_ARRAY:
        var_type = "arrayValue"
        field_value = {"values": array2fields(field_value)}
static func dict2timestamp(dict : Dictionary) -> String:
    var dict_values : Array = dict.values()
    dict_values.remove(3)
    dict_values.remove(3)
    return "%04d-%02d-%02dT%02d:%02d:%02d.00Z" % dict_values

Additional function to convert it back from Firebase to GDScript Dictionary

static func timestamp2dict(timestamp : String) -> Dictionary:
    var datetime : Dictionary = {year = 0, month = 0, day = 0, hour = 0, minute = 0, second = 0}
    var dict : PoolStringArray = timestamp.split("T")[0].split("-")
    dict.append_array(timestamp.split("T")[1].split(":"))
    for value in dict.size() :
        datetime[datetime.keys()[value]] = int(dict[value])
    return datetime
fenix-hub commented 3 years ago

This will need to be updated too:

        for field in (doc.fields).keys():
            if (doc.fields)[field].has("mapValue"):
                dict[field] = fields2dict((doc.fields)[field].mapValue)
            elif (doc.fields)[field].has("timestampValue"):
                dict[field] = timestamp2dict((doc.fields)[field].timestampValue)

Should be everything I suppose

Zarasan commented 3 years ago

Yes that is way better than mine, I just did the fix for my needs

fenix-hub commented 3 years ago

Yes that is way better than mine, I just did the fix for my needs

No problem, it's just to keep the style of the code :) Next update will implement this so you can use these features.

WolfgangSenff commented 3 years ago

Closed by #173.