gcpfirestore

package
v0.17.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 26, 2019 License: Apache-2.0 Imports: 29 Imported by: 0

Documentation

Overview

Package gcpfirestore provides a docstore implementation backed by Google Cloud Firestore. Use OpenCollection to construct a *docstore.Collection.

Docstore types not supported by the Go firestore client, cloud.google.com/go/firestore:

  • unsigned integers: encoded is int64s
  • arrays: encoded as Firestore array values

Firestore types not supported by Docstore:

  • Document reference (a pointer to another Firestore document)

URLs

For docstore.OpenCollection, gcpfirestore registers for the scheme "firestore". The default URL opener will create a connection using default credentials from the environment, as described in https://cloud.google.com/docs/authentication/production. To customize the URL opener, or for more details on the URL format, see URLOpener. See https://github.com/cornelk/go-cloud/concepts/urls/ for background information.

As

gcpfirestore exposes the following types for as functions. The pb package is google.golang.org/genproto/googleapis/firestore/v1. The firestore package is cloud.google.com/go/firestore/apiv1.

  • Collection.As: *firestore.Client
  • ActionList.BeforeDo: *pb.BatchGetDocumentsRequest or *pb.CommitRequest.
  • Query.BeforeQuery: *pb.RunQueryRequest
  • DocumentIterator: firestore.Firestore_RunQueryClient
  • Error: *google.golang.org/grpc/status.Status

Queries

Firestore allows only one field in a query to be compared with an inequality operator (one other than "="). This driver selects the first field in a Where clause with an inequality to pass to Firestore and handles the rest locally. For example, if the query specifies the three clauses A > 1, B > 2 and A < 3, then A > 1 and A < 3 will be sent to Firestore, and the results will be filtered by B > 2 in this driver.

Firestore requires a composite index if a query contains both an equality and an inequality comparison. This driver returns an error if the necessary index does not exist. You must create the index manually. See https://cloud.google.com/firestore/docs/query-data/indexing for details.

See https://cloud.google.com/firestore/docs/query-data/queries for more information on Firestore queries.

Example (OpenCollectionFromURL)
package main

import (
	"context"
	"log"

	"github.com/cornelk/go-cloud/docstore"
)

func main() {
	// PRAGMA: This example is used on github.com/cornelk/go-cloud; PRAGMA comments adjust how it is shown and can be ignored.
	// PRAGMA: On github.com/cornelk/go-cloud, add a blank import: _ "github.com/cornelk/go-cloud/docstore/gcpfirestore"
	// PRAGMA: On github.com/cornelk/go-cloud, hide lines until the next blank line.
	ctx := context.Background()

	// docstore.OpenCollection creates a *docstore.Collection from a URL.
	const url = "firestore://projects/my-project/databases/(default)/documents/my-collection?name_field=userID"
	coll, err := docstore.OpenCollection(ctx, url)
	if err != nil {
		log.Fatal(err)
	}
	defer coll.Close()
}
Output:

Index

Examples

Constants

View Source
const Scheme = "firestore"

Scheme is the URL scheme firestore registers its URLOpener under on docstore.DefaultMux.

Variables

View Source
var Set = wire.NewSet(
	Dial,
	wire.Struct(new(URLOpener), "Client"),
)

Set holds Wire providers for this package.

Functions

func CollectionResourceID

func CollectionResourceID(projectID, collPath string) string

CollectionResourceID constructs a resource ID for a collection from the project ID and the collection path. See the OpenCollection example for use.

func Dial

func Dial(ctx context.Context, ts gcp.TokenSource) (*vkit.Client, func(), error)

Dial returns a client to use with Firestore and a clean-up function to close the client after used.

func OpenCollection

func OpenCollection(client *vkit.Client, collResourceID, nameField string, opts *Options) (*docstore.Collection, error)

OpenCollection creates a *docstore.Collection representing a Firestore collection.

collResourceID must be of the form "project/<projectID>/databases/(default)/documents/<collPath>". <collPath> may be a top-level collection, like "States", or it may be a path to a nested collection, like "States/Wisconsin/Cities". See https://cloud.google.com/firestore/docs/reference/rest/ for more detail.

gcpfirestore requires that a single field, nameField, be designated the primary key. Its values must be strings, and must be unique over all documents in the collection. The primary key must be provided to retrieve a document.

Example
package main

import (
	"context"
	"log"

	"github.com/cornelk/go-cloud/docstore/gcpfirestore"
	"github.com/cornelk/go-cloud/gcp"
)

func main() {
	// PRAGMA: This example is used on github.com/cornelk/go-cloud; PRAGMA comments adjust how it is shown and can be ignored.
	// PRAGMA: On github.com/cornelk/go-cloud, hide lines until the next blank line.
	ctx := context.Background()

	creds, err := gcp.DefaultCredentials(ctx)
	if err != nil {
		log.Fatal(err)
	}
	client, _, err := gcpfirestore.Dial(ctx, creds.TokenSource)
	if err != nil {
		log.Fatal(err)
	}
	resourceID := gcpfirestore.CollectionResourceID("my-project", "my-collection")
	coll, err := gcpfirestore.OpenCollection(client, resourceID, "userID", nil)
	if err != nil {
		log.Fatal(err)
	}
	defer coll.Close()
}
Output:

func OpenCollectionWithNameFunc

func OpenCollectionWithNameFunc(client *vkit.Client, collResourceID string, nameFunc func(docstore.Document) string, opts *Options) (*docstore.Collection, error)

OpenCollectionWithNameFunc creates a *docstore.Collection representing a Firestore collection.

collResourceID must be of the form "project/<projectID>/databases/(default)/documents/<collPath>". <collPath> may be a top-level collection, like "States", or it may be a path to a nested collection, like "States/Wisconsin/Cities".

The nameFunc argument is function that accepts a document and returns the value to be used for the document's primary key. It should return the empty string if the document is missing the information to construct a name. This will cause all actions, even Create, to fail.

Providing a function to construct the primary key is useful in two situations: if your desired primary key field is not a string, or if there is more than one field you want to use as a primary key.

For the collection to be usable with Query.Delete and Query.Update, nameFunc must work with both map and struct types representing the same underlying data structure. See github.com/cornelk/go-cloud/docstore/drivertest.HighScoreKey for an example.

Example
package main

import (
	"context"
	"log"

	"github.com/cornelk/go-cloud/docstore"
	"github.com/cornelk/go-cloud/docstore/gcpfirestore"
	"github.com/cornelk/go-cloud/gcp"
)

func main() {
	// PRAGMA: This example is used on github.com/cornelk/go-cloud; PRAGMA comments adjust how it is shown and can be ignored.
	// PRAGMA: On github.com/cornelk/go-cloud, hide lines until the next blank line.
	ctx := context.Background()
	type HighScore struct {
		Game   string
		Player string
	}

	creds, err := gcp.DefaultCredentials(ctx)
	if err != nil {
		log.Fatal(err)
	}
	client, _, err := gcpfirestore.Dial(ctx, creds.TokenSource)
	if err != nil {
		log.Fatal(err)
	}

	// The name of a document is constructed from the Game and Player fields.
	nameFromDocument := func(doc docstore.Document) string {
		hs := doc.(*HighScore)
		return hs.Game + "|" + hs.Player
	}

	resourceID := gcpfirestore.CollectionResourceID("my-project", "my-collection")
	coll, err := gcpfirestore.OpenCollectionWithNameFunc(client, resourceID, nameFromDocument, nil)
	if err != nil {
		log.Fatal(err)
	}
	defer coll.Close()
}
Output:

Types

type Options

type Options struct {
	// If true, allow queries that require client-side evaluation of filters (Where clauses)
	// to run.
	AllowLocalFilters bool
	// The name of the field holding the document revision.
	// Defaults to docstore.DefaultRevisionField.
	RevisionField string

	// The maximum number of RPCs that can be in progress for a single call to
	// ActionList.Do.
	// If less than 1, there is no limit.
	MaxOutstandingActionRPCs int
}

Options contains optional arguments to the OpenCollection functions.

type URLOpener

type URLOpener struct {
	// Client must be set to a non-nil client authenticated with Cloud Firestore
	// scope or equivalent.
	Client *vkit.Client
}

URLOpener opens firestore URLs like "firestore://projects/myproject/databases/(default)/documents/mycollection?name_field=myID".

See https://firebase.google.com/docs/firestore/data-model for more details.

The following query parameters are supported:

  • name_field (required): gcpfirestore requires that a single string field,

name_field, be designated the primary key. Its values must be unique over all documents in the collection, and the primary key must be provided to retrieve a document.

func (*URLOpener) OpenCollectionURL

func (o *URLOpener) OpenCollectionURL(ctx context.Context, u *url.URL) (*docstore.Collection, error)

OpenCollectionURL opens a docstore.Collection based on u.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL