Skip to content

Instantly share code, notes, and snippets.

@roboncode
Last active July 31, 2025 15:03
Show Gist options
  • Select an option

  • Save roboncode/d8592d3a6ca3704a92ff2c35baf8456a to your computer and use it in GitHub Desktop.

Select an option

Save roboncode/d8592d3a6ca3704a92ff2c35baf8456a to your computer and use it in GitHub Desktop.

Revisions

  1. roboncode revised this gist Nov 28, 2020. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion firestore.go
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    package tran
    package transform

    import (
    "reflect"
  2. roboncode revised this gist Nov 28, 2020. 1 changed file with 9 additions and 9 deletions.
    18 changes: 9 additions & 9 deletions firestore.go
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    package transform
    package tran

    import (
    "reflect"
    @@ -14,24 +14,24 @@ const (

    type FirestoreMap map[string]interface{}

    func ToFirestoreMap(s interface{}) FirestoreMap {
    var result = parseData(s)
    func ToFirestoreMap(value interface{}) FirestoreMap {
    var result = parseData(value)
    return result.(FirestoreMap)
    }

    func isZeroOfUnderlyingType(x interface{}) bool {
    return reflect.DeepEqual(x, reflect.Zero(reflect.TypeOf(x)).Interface())
    }

    func parseData(s interface{}) interface{} {
    if s == nil {
    func parseData(value interface{}) interface{} {
    if value == nil {
    return nil
    }
    var firestoreMap = FirestoreMap{}
    var tag string
    var value interface{}
    //var value interface{}
    var fieldCount int
    var val = reflect.ValueOf(s)
    var val = reflect.ValueOf(value)

    switch value.(type) {
    case time.Time, *time.Time:
    @@ -65,7 +65,7 @@ func parseData(s interface{}) interface{} {
    }
    return firestoreMap
    }
    return s
    return value
    }

    func setValue(firestoreMap FirestoreMap, tag string, value interface{}) {
    @@ -80,4 +80,4 @@ func setValue(firestoreMap FirestoreMap, tag string, value interface{}) {
    }
    }
    firestoreMap[tagValues[0]] = parseData(value)
    }
    }
  3. roboncode revised this gist Nov 28, 2020. 1 changed file with 4 additions and 1 deletion.
    5 changes: 4 additions & 1 deletion firestore.go
    Original file line number Diff line number Diff line change
    @@ -15,7 +15,8 @@ const (
    type FirestoreMap map[string]interface{}

    func ToFirestoreMap(s interface{}) FirestoreMap {
    return parseData(s).(FirestoreMap)
    var result = parseData(s)
    return result.(FirestoreMap)
    }

    func isZeroOfUnderlyingType(x interface{}) bool {
    @@ -54,13 +55,15 @@ func parseData(s interface{}) interface{} {
    value = val.Elem().Field(i).Interface()
    setValue(firestoreMap, tag, value)
    }
    return firestoreMap
    case reflect.Struct, reflect.Interface:
    fieldCount = val.NumField()
    for i := 0; i < fieldCount; i++ {
    tag = val.Type().Field(i).Tag.Get(tagName)
    value = val.Field(i).Interface()
    setValue(firestoreMap, tag, value)
    }
    return firestoreMap
    }
    return s
    }
  4. roboncode revised this gist Nov 28, 2020. 1 changed file with 1 addition and 3 deletions.
    4 changes: 1 addition & 3 deletions firestore.go
    Original file line number Diff line number Diff line change
    @@ -61,10 +61,8 @@ func parseData(s interface{}) interface{} {
    value = val.Field(i).Interface()
    setValue(firestoreMap, tag, value)
    }
    default:
    return s
    }
    return firestoreMap
    return s
    }

    func setValue(firestoreMap FirestoreMap, tag string, value interface{}) {
  5. roboncode created this gist Nov 28, 2020.
    82 changes: 82 additions & 0 deletions firestore.go
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,82 @@
    package transform

    import (
    "reflect"
    "strings"
    "time"
    )

    const (
    tagName = "firestore"
    tagOmitEmpty = "omitempty"
    delimiter = ","
    )

    type FirestoreMap map[string]interface{}

    func ToFirestoreMap(s interface{}) FirestoreMap {
    return parseData(s).(FirestoreMap)
    }

    func isZeroOfUnderlyingType(x interface{}) bool {
    return reflect.DeepEqual(x, reflect.Zero(reflect.TypeOf(x)).Interface())
    }

    func parseData(s interface{}) interface{} {
    if s == nil {
    return nil
    }
    var firestoreMap = FirestoreMap{}
    var tag string
    var value interface{}
    var fieldCount int
    var val = reflect.ValueOf(s)

    switch value.(type) {
    case time.Time, *time.Time:
    return value
    }

    switch val.Kind() {
    case reflect.Map:
    for _, key := range val.MapKeys() {
    val := val.MapIndex(key)
    firestoreMap[key.String()] = parseData(val.Interface())
    }
    return firestoreMap
    case reflect.Ptr:
    if val.IsNil() {
    return nil
    }
    fieldCount = val.Elem().NumField()
    for i := 0; i < fieldCount; i++ {
    tag = val.Elem().Type().Field(i).Tag.Get(tagName)
    value = val.Elem().Field(i).Interface()
    setValue(firestoreMap, tag, value)
    }
    case reflect.Struct, reflect.Interface:
    fieldCount = val.NumField()
    for i := 0; i < fieldCount; i++ {
    tag = val.Type().Field(i).Tag.Get(tagName)
    value = val.Field(i).Interface()
    setValue(firestoreMap, tag, value)
    }
    default:
    return s
    }
    return firestoreMap
    }

    func setValue(firestoreMap FirestoreMap, tag string, value interface{}) {
    if tag == "" || tag == "-" || value == nil {
    return
    }

    tagValues := strings.Split(tag, delimiter)
    if strings.Contains(tag, tagOmitEmpty) {
    if isZeroOfUnderlyingType(value) {
    return
    }
    }
    firestoreMap[tagValues[0]] = parseData(value)
    }