I have a microcontroller sending data to a topic in Google Cloud Pub/Sub service, and I'm receiving the data successfully:
I created a Cloud function in Firebase with the purpouse of store the received data in a Database every time a message arrives in a particular topic named "sensors".
This is my index.js file:
const functions = require("firebase-functions");
PubSub = require(`@google-cloud/pubsub`),
admin = require("firebase-admin");
const app = admin.initializeApp();
const firestore = app.firestore();
var num = 0;
firestore.settings({ timestampsInSnapshots: true });
const auth = app.auth();
exports.deviceState = functions.pubsub.topic('sensors').onPublish(async (message) => {
const deviceId = message.attributes.deviceId;
const deviceRef = firestore.doc(`device-configs/${deviceId}`);
try {
await deviceRef.update({ 'state': message.json, 'online': true, 'timestamp' : admin.firestore.Timestamp.now() });
console.log(`State updated for ${deviceId}`);
} catch (error) {
console.error(`${deviceId} not yet registered to a user`, error);
}
});
It's my understanding that this Cloud Function should create and populate a Database, but there's no database in my Firebase project, here are the logs from Firebase:
9:18:51.107 PM
deviceState
Function execution started
9:18:51.148 PM
deviceState
at Object.onReceiveStatus (/workspace/node_modules/@grpc/grpc-js/build/src/client.js:179:52)
9:18:51.148 PM
deviceState
aquast1-dev not yet registered to a user Error: 5 NOT_FOUND: No document to update: projects/project-id/databases/(default)/documents/device-configs/aquast1-dev
9:18:51.148 PM
deviceState
at Object.callErrorFromStatus (/workspace/node_modules/@grpc/grpc-js/build/src/call.js:31:26)
9:18:51.148 PM
deviceState
at Object.onReceiveStatus (/workspace/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:336:141)
9:18:51.148 PM
deviceState
at Object.onReceiveStatus (/workspace/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:299:181)
9:18:51.148 PM
deviceState
at /workspace/node_modules/@grpc/grpc-js/build/src/call-stream.js:145:78
9:18:51.148 PM
deviceState
at processTicksAndRejections (internal/process/task_queues.js:77:11)
9:18:51.148 PM
deviceState
Caused by: Error
9:18:51.148 PM
deviceState
at WriteBatch.commit (/workspace/node_modules/@google-cloud/firestore/build/src/write-batch.js:417:23)
9:18:51.148 PM
deviceState
at DocumentReference.update (/workspace/node_modules/@google-cloud/firestore/build/src/reference.js:393:14)
9:18:51.148 PM
deviceState
at /workspace/index.js:17:23
9:18:51.148 PM
deviceState
at cloudFunction (/workspace/node_modules/firebase-functions/lib/cloud-functions.js:135:23)
9:18:51.148 PM
deviceState
at /layers/google.nodejs.functions-framework/functions-framework/node_modules/@google-cloud/functions-framework/build/src/invoker.js:199:28
9:18:51.148 PM
deviceState
at runMicrotasks (<anonymous>)
9:18:51.148 PM
deviceState
at processTicksAndRejections (internal/process/task_queues.js:95:5) {
9:18:51.148 PM
deviceState
code: 5,
9:18:51.148 PM
deviceState
details: 'No document to update: projects/project-id/databases/(default)/documents/device-configs/aquast1-dev',
9:18:51.148 PM
deviceState
metadata: Metadata { internalRepr: Map(0) {}, options: {} },
9:18:51.148 PM
deviceState
note: 'Exception occurred in retry method that was not classified as transient'
9:18:51.148 PM
deviceState
}
9:18:51.149 PM
deviceState
Function execution took 43 ms, finished with status: 'ok'
Logs are subject to Cloud Logging's
Can someone point me in the right direction here? What am I missing?
CodePudding user response:
it seems you are trying to update a document that doesn't exists, try to use "set" instead of "update", you can always pass { merge: true } as an option then it will behave like an update
await deviceRef.set({
'state': message.json,
'online': true,
'timestamp' : admin.firestore.Timestamp.now()
}, { merge: true });