func()

in db/ref.go [245:284]


func (r *Ref) Transaction(ctx context.Context, fn UpdateFn) error {
	req := &internal.Request{
		Method: http.MethodGet,
		Opts: []internal.HTTPOption{
			internal.WithHeader("X-Firebase-ETag", "true"),
		},
	}
	resp, err := r.sendAndUnmarshal(ctx, req, nil)
	if err != nil {
		return err
	}

	etag := resp.Header.Get("Etag")
	for i := 0; i < txnRetries; i++ {
		new, err := fn(&transactionNodeImpl{resp.Body})
		if err != nil {
			return err
		}

		req := &internal.Request{
			Method: http.MethodPut,
			Body:   internal.NewJSONEntity(new),
			Opts: []internal.HTTPOption{
				internal.WithHeader("If-Match", etag),
			},
			SuccessFn: successOrPreconditionFailed,
		}
		resp, err = r.sendAndUnmarshal(ctx, req, nil)
		if err != nil {
			return err
		}

		if resp.Status == http.StatusOK {
			return nil
		}

		etag = resp.Header.Get("ETag")
	}
	return fmt.Errorf("transaction aborted after failed retries")
}