Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

firestore: Checking if structure is empty #11425

Open
vasi1e opened this issue Jan 9, 2025 · 0 comments
Open

firestore: Checking if structure is empty #11425

vasi1e opened this issue Jan 9, 2025 · 0 comments
Assignees
Labels
api: firestore Issues related to the Firestore API. type: bug Error or flaw in code with unintended results or allowing sub-optimal usage patterns.

Comments

@vasi1e
Copy link

vasi1e commented Jan 9, 2025

Is your feature request related to a problem? Please describe.

The data model I am trying to write in firestore contains some nested structures. Like this:

type Address struct {
    Country string `firestore:"country"`
    City string `firestore:"city"`
    PostCode int `firestore:"postcode"`
    Street string `firestore:"street"`
}
type User struct {
   Name string `firestore:"name"`
   AddressInfo Address `firestore:"address,omitempty"`
}

For our business logic is alright if the user do not provide address so in this case the Address object is empty(containing only zero-value fields) and I want to omit it. This tag "omitempty" is not working in this case. The result in firestore is like that:

name: Vasil
address:
    country: ""
    city: ""
    postcode: 0
    street: ""

Describe the solution you'd like

I would want if I said that nested structure should be omitted when empty then this data is skipped in the firestore document:

name: Vasil

I figured out this function is responsible for checking if field is empty or not. Adding one addition case for a struct as simple as that fixes my problem:

func isEmptyValue(v reflect.Value) bool {
	switch v.Kind() {
	case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
		return v.Len() == 0
	case reflect.Bool:
		return !v.Bool()
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return v.Int() == 0
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
		return v.Uint() == 0
	case reflect.Float32, reflect.Float64:
		return v.Float() == 0
	case reflect.Interface, reflect.Ptr:
		return v.IsNil()
	case reflect.Struct:
		{
			for i := 0; i < v.NumField(); i++ {
				if !isEmptyValue(v.Field(i)) {
					return false
				}
			}

			return true
		}
	}
	if v.Type() == typeOfGoTime {
		return v.Interface().(time.Time).IsZero()
	}
	return false
}

Is there specific reason why this is missed in first place? I could not find any information why I cannot say "omitempty" on nested struct?

Describe alternatives you've considered

Changing the nested structure type to be a reference to this object works with "omitempty" but I have to change the code base and introduce a reference when is not needed. Other approach I think of is adding the tag "omitempty" on the fields of the nested structures:

type Address struct {
    Country string `firestore:"country,omitempty"`
    City string `firestore:"city,omitempty"`
    PostCode int `firestore:"postcode,omitempty"`
    Street string `firestore:"street,omitempty"`
}
type User struct {
   Name string `firestore:"name"`
   AddressInfo Address `firestore:"address,omitempty"`
}

Then this result in the firestore document as empty map:

name: Vasil
address
@vasi1e vasi1e added the triage me I really want to be triaged. label Jan 9, 2025
@product-auto-label product-auto-label bot added the api: firestore Issues related to the Firestore API. label Jan 9, 2025
@bhshkh bhshkh added type: bug Error or flaw in code with unintended results or allowing sub-optimal usage patterns. and removed triage me I really want to be triaged. labels Jan 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api: firestore Issues related to the Firestore API. type: bug Error or flaw in code with unintended results or allowing sub-optimal usage patterns.
Projects
None yet
Development

No branches or pull requests

2 participants