Firebase 如何将云Firestore与Gin框架连接?

Firebase 如何将云Firestore与Gin框架连接?,firebase,go,google-cloud-firestore,go-gin,Firebase,Go,Google Cloud Firestore,Go Gin,如何将云Firestore与Gin框架连接?使用main.go和route.go。我已经在云firestore上创建了一个项目,集合为“用户” 这是我的主要任务 package main import ( "context" "log" "project/routes" "github.com/gin-gonic/gin" firebase "firebase.

如何将云Firestore与Gin框架连接?使用main.go和route.go。我已经在云firestore上创建了一个项目,集合为“用户”

这是我的主要任务

package main

import (
    "context"
    "log"
    "project/routes"

    "github.com/gin-gonic/gin"

    firebase "firebase.google.com/go"

    "google.golang.org/api/option"
)

const (
    projectID      string = "ProjectID"
    collectionName string = "users"
)

func main() {


    // get the db connection and check for error
    app, err := connectDB()
    if err != nil {
        return
    }

    router := gin.Default()

    // all router have access to the db
    router.Use(dbMiddleware(*app))

    usersGroup := router.Group("users")
    {
        usersGroup.POST("register", routes.UsersRegister)
    }

    router.Run()

}

//connecting the api to the firestore
func connectDB() (c *firebase.App, err error) {
    ctx := context.Background()
    opt := option.WithCredentialsFile("path/to/file.json")
    app, err := firebase.NewApp(ctx, nil, opt)
    if err != nil {
        log.Fatalln(err)
        return nil, err
    }

    client, err := app.Firestore(ctx)
    if err != nil {
        log.Fatalln(err)
        return nil, err
    }
    defer client.Close()
    return app, err
}

// create a middleware that attach the db connection to the context
func dbMiddleware(app firebase.App) gin.HandlerFunc {
    return func(c *gin.Context) {
        c.Set("db", app)
        c.Next()
    }
}
这是routes/users.go

package routes

import (
    "fmt"
    "project/models"
    "net/http"

    firebase "firebase.google.com/go"
    "github.com/gin-gonic/gin"
)

func UsersRegister(c *gin.Context) {
    user := models.User{}
    err := c.ShouldBindJSON(&user)
    if err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
        return
    }
    db, _ := c.Get("db")
    app := db.(firebase.App)
    err = user.Register(&app)
    if err != nil {
        fmt.Println("Error in user.Register()")
        c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
        return
    }

    c.JSON(http.StatusOK, gin.H{
        "user_id": user.ID,
    })

}

package models

import (
    "context"
    "fmt"
    "log"
    "strings"
    "time"

    "cloud.google.com/go/firestore"
    firebase "firebase.google.com/go"

    "github.com/gofrs/uuid"
    "golang.org/x/crypto/bcrypt"
)

const (
    projectID      string = "ProjectId"
    collectionName string = "users"
)

var client *firestore.Client

type User struct {
    ID              uuid.UUID `json:"id"`
    CreatedAt       time.Time `json:"_"`
    UpdatedAt       time.Time `json:"_"`
    FirstName       string    `json:"first_name"`
    LastName        string    `json:"last_name"`
    Email           string    `json:"email"`
    PasswordHash    string    `json:"-"`
    Password        string    `json:"password"`
    PasswordConfirm string    `json:"password_confirm"`
}

func (u *User) Register(app *firebase.App) error {
    if len(u.Password) < 4 || len(u.PasswordConfirm) < 4 {
        return fmt.Errorf("Password must be at least 4 characters long.")
    }

    if u.Password != u.PasswordConfirm {
        return fmt.Errorf("Passwords do not match.")
    }

    if len(u.Email) < 4 {
        return fmt.Errorf("Email must be at least 4 characters long.")
    }

    u.Email = strings.ToLower(u.Email)

    //TO DO check if the email does exist in the db

    // using bcrypt library to hash the password
    pwdHash, err := bcrypt.GenerateFromPassword([]byte(u.Password), bcrypt.DefaultCost)
    if err != nil {
        return fmt.Errorf("There was an error creating your account.")
    }
    u.PasswordHash = string(pwdHash)

    now := time.Now()
    ctx := context.Background()
    defer client.Close()

    if err != nil {
        log.Fatalf(" Failed to create DB")
        return nil
    }
    var user User
    _, _, err = client.Collection(collectionName).Add(ctx, map[string]interface{}{
        "ID":           user.ID,
        "FirstName ":   user.FirstName,
        "LastName":     user.LastName,
        "Email":        user.Email,
        "PasswordHash": user.PasswordHash,
        "CreatedAt":    now,
        "UpdatedAt":    now,
    })
    if err != nil {
        log.Fatalf(" Failed to add new user")
        return nil
    }
    return err

}
这是models/users.go

package routes

import (
    "fmt"
    "project/models"
    "net/http"

    firebase "firebase.google.com/go"
    "github.com/gin-gonic/gin"
)

func UsersRegister(c *gin.Context) {
    user := models.User{}
    err := c.ShouldBindJSON(&user)
    if err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
        return
    }
    db, _ := c.Get("db")
    app := db.(firebase.App)
    err = user.Register(&app)
    if err != nil {
        fmt.Println("Error in user.Register()")
        c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
        return
    }

    c.JSON(http.StatusOK, gin.H{
        "user_id": user.ID,
    })

}

package models

import (
    "context"
    "fmt"
    "log"
    "strings"
    "time"

    "cloud.google.com/go/firestore"
    firebase "firebase.google.com/go"

    "github.com/gofrs/uuid"
    "golang.org/x/crypto/bcrypt"
)

const (
    projectID      string = "ProjectId"
    collectionName string = "users"
)

var client *firestore.Client

type User struct {
    ID              uuid.UUID `json:"id"`
    CreatedAt       time.Time `json:"_"`
    UpdatedAt       time.Time `json:"_"`
    FirstName       string    `json:"first_name"`
    LastName        string    `json:"last_name"`
    Email           string    `json:"email"`
    PasswordHash    string    `json:"-"`
    Password        string    `json:"password"`
    PasswordConfirm string    `json:"password_confirm"`
}

func (u *User) Register(app *firebase.App) error {
    if len(u.Password) < 4 || len(u.PasswordConfirm) < 4 {
        return fmt.Errorf("Password must be at least 4 characters long.")
    }

    if u.Password != u.PasswordConfirm {
        return fmt.Errorf("Passwords do not match.")
    }

    if len(u.Email) < 4 {
        return fmt.Errorf("Email must be at least 4 characters long.")
    }

    u.Email = strings.ToLower(u.Email)

    //TO DO check if the email does exist in the db

    // using bcrypt library to hash the password
    pwdHash, err := bcrypt.GenerateFromPassword([]byte(u.Password), bcrypt.DefaultCost)
    if err != nil {
        return fmt.Errorf("There was an error creating your account.")
    }
    u.PasswordHash = string(pwdHash)

    now := time.Now()
    ctx := context.Background()
    defer client.Close()

    if err != nil {
        log.Fatalf(" Failed to create DB")
        return nil
    }
    var user User
    _, _, err = client.Collection(collectionName).Add(ctx, map[string]interface{}{
        "ID":           user.ID,
        "FirstName ":   user.FirstName,
        "LastName":     user.LastName,
        "Email":        user.Email,
        "PasswordHash": user.PasswordHash,
        "CreatedAt":    now,
        "UpdatedAt":    now,
    })
    if err != nil {
        log.Fatalf(" Failed to add new user")
        return nil
    }
    return err

}

在过去的5天里,我一直在尝试连接firestore,但我在某个地方遇到了问题。提前感谢您的帮助。

您能否尝试编辑您的问题,以减少代码?最好测试问题是与Firestore连接还是Gin中的路由。您可以尝试运行一个简单的Gin服务器,看看它是否可以与postman.try用户结构的字段和指针一起使用。有些字段可能为空。