func DefaultQueryOptions(opts ...QueryOption) Option {
	return func(r *DatabaseRef) error {
		r.rw.Lock()
		defer r.rw.Unlock()
		r.queryOpts = opts
		return nil
	}
}
DefaultQueryOptions is an option that sets the default query options on the
database ref.
package firebase
import (
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/http/httputil"
	"net/url"
	"strconv"
	"time"
	"cloud.google.com/go/compute/metadata"
	"golang.org/x/oauth2"
	"golang.org/x/oauth2/google"
	"github.com/knq/jwt/gserviceaccount"
)
const (
	DefaultTokenExpiration = 1 * time.Hour
)
var requiredScopes = []string{
	"https://www.googleapis.com/auth/userinfo.email",
	"https://www.googleapis.com/auth/firebase.database",
}
type Option func(r *DatabaseRef) error
func URL(urlstr string) Option {
	return func(r *DatabaseRef) error {
		u, err := url.Parse(urlstr)
		if err != nil {
			return fmt.Errorf("could not parse url: %v", err)
		}
		r.url = u
		return nil
	}
}
func ProjectID(projectID string) Option {
	return func(r *DatabaseRef) error {
		if projectID == "" {
			return errors.New("project id cannot be empty")
		}
		err := URL("https://" + projectID + ".firebaseio.com/")(r)
		if err != nil {
			return errors.New("invalid project id")
		}
		return nil
	}
}
func Transport(roundTripper http.RoundTripper) Option {
	return func(r *DatabaseRef) error {
		r.transport = roundTripper
		return nil
	}
}
func WatchBufferLen(len int) Option {
	return func(r *DatabaseRef) error {
		r.watchBufLen = len
		return nil
	}
}
func GoogleServiceAccountCredentialsJSON(buf []byte) Option {
	return func(r *DatabaseRef) error {
		var err error
		gsa, err := gserviceaccount.FromJSON(buf)
		if err != nil {
			return err
		}
		if gsa.ProjectID == "" || gsa.ClientEmail == "" || gsa.PrivateKey == "" {
			return errors.New("google service account credentials missing project_id, client_email or private_key")
		}
		err = ProjectID(gsa.ProjectID)(r)
		if err != nil {
			return err
		}
		ts, err := gsa.TokenSource(nil, requiredScopes...)
		if err != nil {
			return err
		}
		r.source = oauth2.ReuseTokenSource(nil, ts)
		return nil
	}
}
func GoogleServiceAccountCredentialsFile(path string) Option {
	return func(r *DatabaseRef) error {
		buf, err := ioutil.ReadFile(path)
		if err != nil {
			return fmt.Errorf("could not read google service account credentials file: %v", err)
		}
		return GoogleServiceAccountCredentialsJSON(buf)(r)
	}
}
func GoogleComputeCredentials(serviceAccount string) Option {
	return func(r *DatabaseRef) error {
		var err error
		scopes, err := metadata.Scopes(serviceAccount)
		if err != nil {
			return err
		}
		for _, s := range requiredScopes {
			if !sliceContains(scopes, s) {
				return fmt.Errorf("missing required scope %s in compute metadata", s)
			}
		}
		projectID, err := metadata.ProjectID()
		if err != nil {
			return err
		}
		if projectID == "" {
			return errors.New("could not retrieve project id from compute metadata service")
		}
		err = ProjectID(projectID)(r)
		if err != nil {
			return err
		}
		return Transport(&oauth2.Transport{
			Source: google.ComputeTokenSource(serviceAccount),
			Base:   r.transport,
		})(r)
	}
}