-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Open
toshi38/google-cloud-go
#1Labels
api: firestoreIssues related to the Firestore API.Issues related to the Firestore API.triage meI really want to be triaged.I really want to be triaged.
Description
Client
Firestore
Environment
- Firestore Emulator (via gcloud emulators firestore start or testcontainers)
- macOS / Linux
- go version go1.25
Code and Dependencies
package main
import (
"context"
"fmt"
"log"
"cloud.google.com/go/firestore"
"cloud.google.com/go/firestore/apiv1/firestorepb"
)
func main() {
ctx := context.Background()
// Connect to emulator (FIRESTORE_EMULATOR_HOST must be set)
client, err := firestore.NewClient(ctx, "my-project")
if err != nil {
log.Fatal(err)
}
defer client.Close()
// Create some test data
client.Collection("items").Doc("1").Set(ctx, map[string]interface{}{"active": true})
client.Collection("items").Doc("2").Set(ctx, map[string]interface{}{"active": true})
// Run aggregation query
query := client.Collection("items").Where("active", "==", true)
results, err := query.NewAggregationQuery().WithCount("count").Get(ctx)
if err != nil {
log.Fatal(err)
}
count := results["count"]
fmt.Printf("Type: %T, Value: %v\n", count, count)
// Emulator returns: Type: *firestorepb.Value, Value: integer_value:2
// Production returns: Type: int64, Value: 2
// Workaround required:
switch v := count.(type) {
case int64:
fmt.Println("Got int64:", v)
case *firestorepb.Value:
fmt.Println("Got *firestorepb.Value:", v.GetIntegerValue())
}
}
go.mod
module example
go 1.25
require (
cloud.google.com/go/firestore v1.18.0
)
Expected behavior
AggregationQuery.Get() should return consistent native Go types (e.g., int64 for COUNT) in the AggregationResult map, regardless of whether running against production Firestore or the Firestore emulator.
Actual behavior
- Production Firestore: Returns int64
- Firestore Emulator: Returns *firestorepb.Value
This forces users to handle both types with a type switch.
Copilot thinks the issue is in query.go where aggregation results are processed, I haven't verified that myself:
// query.go lines ~1751-1752
for k, v := range f {
resp[k] = v // v is *pb.Value, assigned directly without conversion
}
The fix should use createFromProtoValue() to convert proto values to native Go types:
for k, v := range f {
converted, err := createFromProtoValue(v, a.query.c)
if err != nil {
return nil, err
}
resp[k] = converted
}
Additional context
- Affects all aggregation types: COUNT, SUM, AVG
- Confirmed the same code exists in v1.18.0 through v1.21.0 (latest)
- Similar issue was reported for Firebase JS SDK: Firestore AggregateQuery is now broken when using the Firestore emulator with firebase-tools version
13.3.1specifically on firebase-js-sdk firebase/firebase-tools#6808
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
api: firestoreIssues related to the Firestore API.Issues related to the Firestore API.triage meI really want to be triaged.I really want to be triaged.