Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Adakah saya memerlukan perjalanan pergi balik tambahan ke firestore untuk membaca medan cap masa yang dibuat dan dikemas kini?

Adakah saya memerlukan perjalanan pergi balik tambahan ke firestore untuk membaca medan cap masa yang dibuat dan dikemas kini?

PHPz
PHPzke hadapan
2024-02-11 18:36:091194semak imbas

我是否需要额外往返 firestore 来读取创建和更新的时间戳字段?

Apabila menggunakan Firestore, anda mungkin tertanya-tanya sama ada perjalanan pergi balik tambahan diperlukan untuk membaca medan cap masa yang dibuat dan dikemas kini. Jawapannya tidak. Firestore secara automatik menyediakan cap masa penciptaan dan kemas kini untuk setiap dokumen, dan anda boleh mendapatkan maklumat masa yang sepadan dengan merujuk medan ini. Dengan cara ini, anda tidak memerlukan operasi tambahan untuk membaca medan cap masa dan anda boleh mendapatkan masa penciptaan dan kemas kini dokumen dengan lebih mudah. Reka bentuk ini menjadikan proses pembangunan lebih cekap dan dipermudahkan, mengelakkan kod dan permintaan yang tidak perlu.

Isi soalan

  1. Baiklah, ini saya go 中有一个 rest api ,它使用 firestore 存储 ticket Sumber. Untuk ini saya gunakan: firestore go client

  2. Saya mahu boleh mengisih dokumen saya dengan date 创建/更新日期 jadi mengikut dokumen saya menyimpan 2 medan ini sebagai cap masa dalam dokumen.

  3. Saya menggunakan label servertimestamp pada kedua-dua medan. Dengan melakukan ini, nilai itu mestilah masa yang diambil untuk pelayan firestore memproses permintaan.

  4. Respons http untuk operasi kemas kini harus mengandungi badan berikut:

{
 "ticket": {
   "id": "af41766e-76ea-43b5-86c1-8ba382edd4dc",
   "title": "ticket updated title",
   "price": 9,
   "date_created": "2023-01-06 09:07:24",
   "date_updated": "2023-01-06 10:08:24"
 }
}

Ini bermakna selepas saya mengemas kini dokumen tiket, tiada apa-apa selain nilai medan title 或 price 之外,我还需要更新 date_updated yang dikemas kini.

Ia berfungsi pada masa ini, tetapi saya ingin tahu sama ada cara saya mengekod adalah cara untuk melakukannya. Seperti yang anda lihat dalam contoh kod, saya menggunakan transaksi untuk mengemas kini tiket. Saya tidak menemui cara untuk mendapatkan semula nilai kemas kini medan dateupdated selain membaca tiket yang dikemas kini sekali lagi.

Entiti domain ditakrifkan seperti berikut:

package tixer

import (
    "context"
    "time"

    "github.com/google/uuid"
)

type (

    // ticketid represents a unique identifier for a ticket.
    // it's a domain type.
    ticketid uuid.uuid

    // ticket represents an individual ticket in the system.
    // it's a domain type.
    ticket struct {
        id          ticketid
        title       string
        price       float64
        datecreated time.time
        dateupdated time.time
    }

)

Saya akan melampirkan komunikasi dengan firestore dari sudut penciptaan dan kemas kini di sini:

// Storer persists tickets in Firestore.
type Storer struct {
    client *firestore.Client
}

func NewStorer(client *firestore.Client) *Storer {
    return &Storer{client}
}

func (s *Storer) CreateTicket(ctx context.Context, ticket *tixer.Ticket) error {
    writeRes, err := s.client.Collection("tickets").Doc(ticket.ID.String()).Set(ctx, createTicket{
        Title: ticket.Title,
        Price: ticket.Price,
    })

    // In this case writeRes.UpdateTime is the time the document was created.
    ticket.DateCreated = writeRes.UpdateTime

    return err
}

func (s *Storer) UpdateTicket(ctx context.Context, ticket *tixer.Ticket) error {
    docRef := s.client.Collection("tickets").Doc(ticket.ID.String())
    err := s.client.RunTransaction(ctx, func(ctx context.Context, tx *firestore.Transaction) error {
        doc, err := tx.Get(docRef)
        if err != nil {
            switch {
            case status.Code(err) == codes.NotFound:
                return tixer.ErrTicketNotFound
            default:
                return err
            }
        }
        var t persistedTicket
        if err := doc.DataTo(&t); err != nil {
            return err
        }
        t.ID = doc.Ref.ID

        if ticket.Title != "" {
            t.Title = ticket.Title
        }
        if ticket.Price != 0 {
            t.Price = ticket.Price
        }

        return tx.Set(docRef, updateTicket{
            Title:       t.Title,
            Price:       t.Price,
            DateCreated: t.DateCreated,
        })
    })
    if err != nil {
        return err
    }

    updatedTicket, err := s.readTicket(ctx, ticket.ID)
    if err != nil {
        return err
    }
    *ticket = updatedTicket

    return nil
}

func (s *Storer) readTicket(ctx context.Context, id tixer.TicketID) (tixer.Ticket, error) {
    doc, err := s.client.Collection("tickets").Doc(id.String()).Get(ctx)
    if err != nil {
        switch {
        case status.Code(err) == codes.NotFound:
            return tixer.Ticket{}, tixer.ErrTicketNotFound
        default:
            return tixer.Ticket{}, err
        }
    }

    var t persistedTicket
    if err := doc.DataTo(&t); err != nil {
        return tixer.Ticket{}, err
    }
    t.ID = doc.Ref.ID

    return toDomainTicket(t), nil
}

type (
    // persistedTicket represents a stored ticket in Firestore.
    persistedTicket struct {
        ID          string    `firestore:"id"`
        Title       string    `firestore:"title"`
        Price       float64   `firestore:"price"`
        DateCreated time.Time `firestore:"dateCreated"`
        DateUpdated time.Time `firestore:"dateUpdate"`
    }

    // createTicket contains the data needed to create a Ticket in Firestore.
    createTicket struct {
        Title       string    `firestore:"title"`
        Price       float64   `firestore:"price"`
        DateCreated time.Time `firestore:"dateCreated,serverTimestamp"`
        DateUpdated time.Time `firestore:"dateUpdate,serverTimestamp"`
    }
    // updateTicket contains the data needed to update a Ticket in Firestore.
    updateTicket struct {
        Title       string    `firestore:"title"`
        Price       float64   `firestore:"price"`
        DateCreated time.Time `firestore:"dateCreated"`
        DateUpdated time.Time `firestore:"dateUpdate,serverTimestamp"`
    }
)

func toDomainTicket(t persistedTicket) tixer.Ticket {
    return tixer.Ticket{
        ID:          tixer.TicketID(uuid.MustParse(t.ID)),
        Title:       t.Title,
        Price:       t.Price,
        DateCreated: t.DateCreated,
        DateUpdated: t.DateUpdated,
    }
}

Penyelesaian

Jika saya faham dengan betul, medan DateUpdated ialah cap waktu sebelah pelayan, yang bermaksud nilainya ditentukan oleh pelayan apabila ia menulis nilai pada lapisan storan (kononnya transformasi medan). Memandangkan operasi tulis dalam SDK Firestore tidak mengembalikan data hasil operasi, satu-satunya cara untuk mendapatkan semula nilai itu ke dalam aplikasi sebenarnya adalah dengan melakukan operasi baca tambahan selepas menulis untuk mendapatkannya.

SDK tidak akan melakukan bacaan ini secara automatik kerana ia adalah operasi bercaj dan tidak diperlukan dalam banyak kes. Jadi dengan meminta kod anda melaksanakan bacaan itu, anda boleh memutuskan sama ada untuk menanggung kos ini.

Atas ialah kandungan terperinci Adakah saya memerlukan perjalanan pergi balik tambahan ke firestore untuk membaca medan cap masa yang dibuat dan dikemas kini?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam