首页 > 解决方案 > How to work with context global variables in Golang?

问题描述

I am trying to get all documents from a Firestore database and things were working fine.

But then I decided to make the context and client variable global, so that I won't have to deal with passing them as parameters everytime.

Things broke after that.

The error I get is: panic: runtime error: invalid memory address or nil pointer dereference

and according to the stack trace, it occurs when I try to: client.Collection("dummy").Documents(ctx)

What can I do to resolve this?

And how can I efficiently work with global variables in my case?

My code for reference:

package main

import (
    "context"
    "fmt"
    "log"

    "cloud.google.com/go/firestore"
    firebase "firebase.google.com/go"
    "google.golang.org/api/iterator"
    "google.golang.org/api/option"
)

var (
    ctx    context.Context
    client *firestore.Client
)

func init() {
    ctx := context.Background()
    keyFile := option.WithCredentialsFile("serviceAccountKey.json")
    app, err := firebase.NewApp(ctx, nil, keyFile)
    if err != nil {
        log.Fatalln(err)
    }

    client, err = app.Firestore(ctx)
    if err != nil {
        log.Fatalln(err)
    }
    fmt.Println("Connection to Firebase Established!")
}

func getDocuments(collectionName string) {
    iter := client.Collection("dummy").Documents(ctx)

    for {
        doc, err := iter.Next()
        if err == iterator.Done {
            break
        }
        if err != nil {
            log.Fatalf("Failed to iterate: %v", err)
        }
        fmt.Println(doc.Data()["question"])
    }
}

func main() {
    getDocuments("dummy")
    defer client.Close()
}

标签: go

解决方案


您收到该错误是因为您从未将任何内容分配给包级别ctx变量,因此它仍然是nil.

在内部init()使用创建局部变量的短变量声明:

ctx := context.Background()

如果您更改为 simple assignment,它将为现有的包级ctx变量分配一个值:

ctx = context.Background()

尽管使用“全局”变量来存储非全局变量是不好的做法。你应该只是通过ctx它需要的地方。


推荐阅读