Mam kolekcję o nazwie "reklamy"

/ Adverts / {Ridge_id} <- Where Ridge_id jest auto generowane przez Firestore.

I mam moją kolekcję "Użytkownicy" / Użytkownicy / {User_id} <--- gdzie user_id jest zdefiniowany przez nazwę użytkownika

Więc wewnątrz dokumentów "Adverts" mam następną mapę

user_data:{
    avatar_url: "",
    first_name: "example name",
    last_name: "example last name",
    rating: 5,
    username: "exampleusername"
}

Ta informacja pochodzi z dokumentu użytkownika za każdym razem, gdy tworzona jest ogłoszenie. Chcę więc zaktualizować tę mapę w kolekcji reklam, za każdym razem, gdy użytkownik aktualizuje swoje dane.

Czy można zaktualizować te pola z partią, zakładając, że może istnieć więcej niż jeden dokument na reklamach? (Próbuję uniknąć czytania wszystkich plików i przepisania ich, chcę tylko pisać)

Próbowałem to osiągnąć (jest funkcją chmuru onupdate):

const before = change.before.data(); // Data before the update
const after = change.after.data(); // Data after the update
const user_id = after.username;

let batch  = db.batch()
let advertsRef = db.collection("adverts").where("user_data.username", "==", user_id)

batch.update(advertsRef, {
    "user_data.avatar_url": after.avatar_url,
    "user_data.first_name": after.first_name,
    "user_data.last_name": after.last_name,
    "user_data.overall_adverts_rating": after.overall_adverts_rating,
    "user_data.username": after.username,
 })

batch.commit().then(()=>{
  console.log("done")
})
.catch(error =>{
  console.log(error)
})

Ale pojawia się następny błąd:

Error: Value for argument "documentRef" is not a valid DocumentReference.
at Object.validateDocumentReference (/workspace/node_modules/@google-cloud/firestore/build/src/reference.js:2034:15)
at WriteBatch.update (/workspace/node_modules/@google-cloud/firestore/build/src/write-batch.js:312:21)
at /workspace/index.js:147:9
at cloudFunction (/workspace/node_modules/firebase-functions/lib/cloud-functions.js:134:23)
at /layers/google.nodejs.functions-framework/functions-framework/node_modules/@google-cloud/functions-framework/build/src/invoker.js:199:28
at processTicksAndRejections (internal/process/task_queues.js:97:5) 

Myślę, że jest to powodować, że mój () nie odnosi się do konkretnego pliku.

0
Luis Quiroga 14 kwiecień 2021, 00:47

1 odpowiedź

Najlepsza odpowiedź

W funkcji w chmurze musisz iterować za pomocą każdej dopasowanej reklamy. To znaczy. Przepisujesz wszystkie dokumenty, które pasują do zapytania, co oznacza, że będziesz musiał przeczytać każdy, i zaktualizować każdy. na przykład

let adverts = await db.collection("adverts").where("user_data.username", "==", user_id).get
for (doc of adverts.docs) {
  doc.user_data = after
  batch.update(doc)
}
await batch.commit()
1
Jim Morrison 14 kwiecień 2021, 00:16