将Cloud Firestore与AppEngine一起使用Go Standard Environment在AppEngline上运行时返回rpc错误

时间:2017-12-05 21:35:06

标签: google-app-engine firebase go google-cloud-firestore

我试图在Go编写的AppEngine(标准环境)应用中使用Firestore。我一直在关注" Getting Started with Cloud Firestore"指南,并且一直在使用firestore package文档来实现一个在我的本地开发服务器上运行它时工作正常的简单示例。

但是,当我部署应用程序并尝试部署的版本时,对DocumentRef.Set()的调用失败并显示错误

rpc error: code = Unavailable desc = all SubConns are in TransientFailure

这是我的代码,可以重现这个问题:

func init() {
    http.HandleFunc("/test", testHandler)
}

type testData struct {
    TestData string `firestore:"myKey,omitempty"`
}

func testHandler(w http.ResponseWriter, r *http.Request) {
    ctx := appengine.NewContext(r)

    var firestoreClient *firestore.Client
    var firebaseApp *firebase.App
    var err error

    conf := &firebase.Config{ProjectID: "my-project"}
    firebaseApp, err = firebase.NewApp(ctx, conf)

    if err != nil {
        fmt.Fprintf(w, "Failed to create a new firestore app: %v", err)
        return
    }

    firestoreClient, err = firebaseApp.Firestore(ctx)
    if err != nil {
        fmt.Fprintf(w, "Failed to create a new firestore client: %v", err)
        return
    }

    data := testData{"my value"}
    _, err = firestoreClient.Collection("testCollection").Doc("testDoc").Set(ctx, data)
    if err != nil {
        fmt.Fprintf(w, "Failed to create a firestore document: %v", err)
        return
    }
    firestoreClient.Close()
    fmt.Fprint(w, "Data stored in Firestore successfully")
}

如前所述,在开发服务器上这很好用。因此,返回的页面包含文本Data stored in Firestore successfully

运行部署的代码时,我得到Failed to create a firestore document: rpc error: code = Unavailable desc = all SubConns are in TransientFailure。为什么我会收到此错误,如何避免此错误?

2 个答案:

答案 0 :(得分:3)

我在Firestore客户端库问题跟踪器中提出了一个issue,看起来情况有点复杂。

使用App Engine时,Firestore客户端库的网络连接将通过App Engine socket library进行。但是套接字仅适用于paid App Engine apps

  

套接字仅适用于付费应用,来自套接字的流量称为传出带宽。套接字也受限于每日和每分钟(突发)配额。

因此,这就是Firestore客户端库失败的原因。对于小规模项目,可以启用App Engine应用程序的计费并仍然保持在免费范围内。如果启用了结算功能,则在部署应用时也可以使用。

但是,如果您居住在欧盟范围内,由于Google policies,您不得为非商业目的使用付费App Engine应用程序:

  

如果您位于欧盟,并且您希望使用Google Cloud Platform服务的唯一目的是没有潜在的经济利益,则不应使用该服务。如果您已开始使用Google Cloud Platform,则应停止使用该服务。请参阅创建,修改或关闭结算帐户,了解如何停止对项目进行结算。

因此,如果您在欧洲或由于某些其他原因无法使用付费App Engine应用程序,您将无法使用Firestore客户端库。

在这种情况下,一种替代方法是使用Firestore REST API代替手动向Firestore发出HTTP请求。这是一项更多的工作,但对于规模较小的项目,它可以工作。

答案 1 :(得分:1)

在AppEngine上,您需要创建一个使用urlfetch服务提供的Http客户端的客户端。

firestore.NewClient()函数接受您可以使用ClientOptions函数创建的WithHTTPCLient()参数。

以下是关于issuing HTTP requests from AppEngine Go的文章。

这应该有所帮助。