6

I'm using the Google Cloud Pub Sub API with NodeJS, as documented here. I'm using Heroku to run my server.

The sample code on the Node JS + Pub Sub page asks me to specify a path to a file:

pubsub = gcloud.pubsub({
    projectId: 'my-project',
    keyFilename: '/path/to/keyfile.json'
});

I typically use Heroku's config vars to store secrets and API keys, but in this case it seems that the GCloud API requires me to specify the path to a file. So, I would need to check in a file into Heroku, but not my GitHub repo.

I have tried the following: Pushing .gitignore files to specific remote and How can I upload my application to github but remove sensitive authorization information? but the trouble is that once I force add (git add -f keyfile.json) the json file and make a commit out of it and make a new branch, I can't push that commit to Heroku because when I do git push heroku master, it says Everything is up to date. In any case, that seems very messy. There has got to be a cleaner way to make Google Cloud work with Heroku.

What should I do?

Community
  • 1
  • 1
ShivanKaul
  • 687
  • 1
  • 8
  • 21

2 Answers2

3

Was answered by the lovely folks over at GoogleCloudPlatform: https://github.com/GoogleCloudPlatform/gcloud-node/issues/761

It's not mentioned in the code sample in the documentation, but you can just add a credentials object and pass that to your config. The credentials object can read env vars.

More information here: https://googlecloudplatform.github.io/gcloud-node/#/authorization.
Updated link: https://googleapis.dev/nodejs/pubsub/latest/global.html#ClientConfig

ShivanKaul
  • 687
  • 1
  • 8
  • 21
  • this link seems to be dead: https://googlecloudplatform.github.io/gcloud-node/#/authorization redirecting to generic page: https://cloud.google.com/nodejs/docs/reference/libraries – Serkan Sep 17 '19 at 22:36
0

Not for nodejs but for GO (GOLANG) keep each field value as a separate key in environment variables and then you will need to do something like this, create struct, convert to json (replacing every \\n to \n in the private_key), feed into option.WithCredentialsJSON:

type credentialsData struct {
    Type                    string `json:"type"`
    ProjectId               string `json:"project_id"`
    PrivateKeyId            string `json:"private_key_id"`
    PrivateKey              string `json:"private_key"`
    ClientEmail             string `json:"client_email"`
    ClientId                string `json:"client_id"`
    AuthUri                 string `json:"auth_uri"`
    TokenUri                string `json:"token_uri"`
    AuthProviderX509CertUrl string `json:"auth_provider_x509_cert_url"`
    ClientX509CertUrl       string `json:"client_x509_cert_url"`
}

func firebase_init() *firebase.App {
    backSlashFix := strings.Replace(os.Getenv("FIREBASE_PRIVATE_KEY"), "\\n", "\n", -1)
    json_cred := &credentialsData{
        Type:                    os.Getenv("FIREBASE_ACCOUNT_TYPE"),
        ProjectId:               os.Getenv("FIREBASE_PROJECT_ID"),
        PrivateKeyId:            os.Getenv("FIREBASE_PRIVATE_KEY_ID"),
        PrivateKey:              backSlashFix,
        ClientEmail:             os.Getenv("FIREBASE_CLIENT_EMAIL"),
        ClientId:                os.Getenv("FIREBASE_CLIENT_ID"),
        AuthUri:                 os.Getenv("FIREBASE_AUTH_URI"),
        TokenUri:                os.Getenv("FIREBASE_TOKEN_URI"),
        AuthProviderX509CertUrl: os.Getenv("FIREBASE_AUTH_PROVIDER_X509_CERT_URL"),
        ClientX509CertUrl:       os.Getenv("FIREBASE_CLIENT_X509_CERT_URL"),
    }

    bytes, e := json.Marshal(json_cred)
    if e != nil {
        panic(fmt.Errorf("Could not create json from credentials struct", e))
    }
    opt := option.WithCredentialsJSON([]byte(string(bytes)))
    app, err := firebase.NewApp(context.Background(), &firebase.Config{ProjectID: "<your project id>"}, opt)
    if err != nil {
        panic(fmt.Errorf("error initializing app: %v", err))
    }

    return app
}
Serkan
  • 160
  • 1
  • 1
  • 7