Firestore Timestamp จะถูกแปลงเป็นแผนที่เมื่อประมวลผลผ่านฟังก์ชันคลาวด์

ฉันมีปัญหากับคลาส firebase.firestore.Timestamp

ฉันกำลังทำงานกับแอป Angular 6 พร้อม firestore ฉันใช้ Timestamps โดยไม่มีปัญหามาสักระยะหนึ่งแล้ว แต่ฉันอยู่ระหว่างการย้ายบริการฝั่งไคลเอ็นต์บางส่วนไปยังฟังก์ชันคลาวด์

ปัญหาคือ:

เมื่อฉันดำเนินการเขียนโดยตรงจากฝั่งไคลเอ็นต์ เช่นนี้:

const doc = { startTimestamp: firebase.firestore.Timestamp.fromDate(new Date()) };
firebase.firestore().doc('some_collection/uid).set(doc);

เอกสารได้รับการเขียนอย่างถูกต้องเพื่อ firestore เป็นการประทับเวลา

อย่างไรก็ตาม เมื่อฉันส่งเอกสารไปยังฟังก์ชันคลาวด์ จากนั้นทำการเขียนจากฟังก์ชัน เอกสารนั้นจะถูกเขียนเป็นแผนที่ ไม่ใช่การประทับเวลา ในทำนองเดียวกัน ถ้าฉันใช้วัตถุ JS Date() แทน firestore.Timestamp มันจะถูกเขียนอย่างถูกต้องจากฝั่งไคลเอ็นต์ แต่เขียนเป็นสตริงจากฟังก์ชันคลาวด์

สิ่งนี้สมเหตุสมผลเนื่องจากเอกสารเป็นเพียง JSON ใน request.body ฉันเดาว่าฉันแค่หวังว่า firestore จะฉลาดพอที่จะจัดการการแปลงโดยปริยาย

สำหรับตอนนี้ ฉันมีวิธีแก้ไขปัญหาเฉพาะหน้าที่เพิ่งแปลงวัตถุเป็น firestore ด้วยตนเอง การประทับเวลาอีกครั้งในฟังก์ชันคลาวด์ แต่ฉันหวังว่าจะมีวิธีแก้ไขที่มีประสิทธิภาพมากกว่านี้ อาจมีบางอย่างฝังอยู่ใน SDK ที่ฉันไม่สามารถค้นหาได้

มีใครเคยเจอและพบวิธีแก้ไขปัญหานี้หรือไม่

ฉันสามารถให้ตัวอย่างโค้ดเพิ่มเติมได้หากจำเป็น


person Alec Daling    schedule 18.11.2018    source แหล่งที่มา


คำตอบ (2)


คาดหวังพฤติกรรมที่คุณกำลังสังเกตอยู่ ไลบรารีไคลเอ็นต์ Firestore มีการตีความพิเศษของวัตถุประเภท Timestamp และจะถูกแปลงเป็นฟิลด์ประเภท Timestamp ในฐานข้อมูลเมื่อเขียน อย่างไรก็ตาม หากคุณพยายามทำให้ออบเจ็กต์การประทับเวลาเป็นอนุกรมเป็น JSON คุณจะได้รับออบเจ็กต์ที่มีส่วนประกอบเป็นมิลลิวินาทีและนาโนวินาทีของการประทับเวลา หากคุณต้องการส่งส่วนประกอบการประทับเวลาเหล่านี้ไปยัง Cloud Functions หรือซอฟต์แวร์ชิ้นอื่น ก็ไม่เป็นไร แต่ซอฟต์แวร์ชิ้นอื่นนั้นจะต้องสร้างวัตถุ Timestamp จริงขึ้นใหม่จากส่วนเหล่านั้นก่อนที่จะเขียนไปยัง Firestore ด้วย Admin SDK หรืออะไรก็ตาม SDK ที่คุณใช้เพื่อจัดการกับ Firestore

person Doug Stevenson    schedule 18.11.2018
comment
ขอบคุณ นั่นคือทั้งหมดที่ฉันต้องการได้ยิน วิธีแก้ปัญหาของฉันดูเหมือนจะทำงานได้ดี แต่ก็รู้สึกไม่สะอาดนัก - person Alec Daling; 18.11.2018

ในโมเดลชั้นเรียนของคุณ ให้ใช้ไฟล์

@ServerTimestamp var timestamp: Date? = null

or

@ServerTimestamp Date timestamp = null

คุณสามารถละเว้นการเริ่มต้นการประทับเวลาได้จากโค้ดของคุณ เช่น new Date()

ตัวอย่าง:

@IgnoreExtraProperties
data class ProductItem(
    var userId: String? = "",
    var avgRating: Double = 0.toDouble(),
    @ServerTimestamp var timestamp: Date? = null
)

or

public class ProductItem() {
    String userId;
    Double avgRating;
    @ServerTimestamp Date timestamp;
}
person Joseph Wambura    schedule 18.11.2018
comment
พูดตามตรงฉันไม่เข้าใจว่ามีอะไรแนะนำที่นี่ ฉันไม่แน่ใจว่าสิ่งนี้เกี่ยวข้องหรือไม่ แต่ฉันต้องการให้โมเดลฝั่งไคลเอ็นต์ของฉันสอดคล้องกับการพิมพ์ที่ส่งคืนจากแบบสอบถาม Firestore ด้วยเหตุนี้ ฉันจึงให้แอตทริบิวต์วันที่ฝั่งไคลเอ็นต์ของฉันพิมพ์เป็นการประทับเวลาแทนที่จะเป็นวันที่ เพราะฉันคาดหวังว่าการประทับเวลาจะถูกส่งกลับโดยการสืบค้น ฉันไม่พบคำอธิบายประกอบ @ServerTimestamp คุณช่วยชี้ให้ฉันดูเอกสารประกอบได้ไหม นอกจากนี้อาจไม่เกี่ยวข้อง แต่ฉันกำลังพยายามรวมวันที่ที่ไม่จำเป็นต้องเป็นเวลาเซิร์ฟเวอร์ปัจจุบัน - person Alec Daling; 18.11.2018