0

In a Firebase Cloud function i am attempting to retrieve data from my Realtime Database and write an update to it as well. This is where i am having trouble.

The function:

const functions = require('firebase-functions');
const admin = require('firebase-admin');

admin.initializeApp();
...

api.post('/messages/add', (request: any, response: any) => {

  const dbRef:any = functions.database.ref(`count/${request.body.chatRoomId}`);

  dbRef.once('value').then((snapshot:any) => {
      let messageCount:number = (snapshot.val() && snapshot.val().messages) || 0;
      messageCount = Number(messageCount + 1);
      dbRef.update({
        messages: messageCount,
        updated: admin.database().database.ServerValue.TIMESTAMP
      });
  });

});

When i call this function from the client, in the firebase cloud console logs, i am seeing the following error:

TypeError: dbRef.once is not a function

I have tried referencing the database in each of the following ways, all of which fail:

functions.database.ref(`count/${request.body.chatRoomId}`).once('value').then((snapshot)) =>

functions.database.ref(`count/${request.body.chatRoomId}`).once('value', (snapshot) =>

admin.database().ref(`count/${request.body.chatRoomId}`).once('value').then((snapshot)) =>

admin.database().ref(`count/${request.body.chatRoomId}`).once('value', (snapshot) =>

When attempting the reference using the Admin SDK via admin.database() i get a different error:

TypeError: Cannot read property 'ServerValue' of undefined
    at dbRef.once.then

Lastly, i can confirm that the value for ${request.body.chatRoomId} is resolving correctly, i had tested this by printing its value to the console.

The answer here shows how to reference the realtime database from the 'event' response within a realtime database listener like onWrite() for example, however my function is not triggered by realtime database changes, but rather is an endpoint reachable from the client.

UPDATE

The answer proposed by Doug Stevenson below is correct but there was also an additional error due to attempting to write a timestamp incorrectly to a field that i had initially excluded which was causing my function to fail despite having tried his solution, thus I have updated the code to reflect this.

First, the answer is to reference the Realtime Database with admin.database()

Second, even though i had tried this, i was still seeing an error, but the error was due to attempting to set a timestamp incorrectly. Thanks to Frank van Puffelen for pointing this out.

This: admin.database().database.ServerValue.TIMESTAMP

Needs to be: admin.database.ServerValue.TIMESTAMP

And with that it works.

2
  • 2
    When posting questions about code, it's very helpful if you provide a MCVE, not just an approximation of the code. We need to see exactly what you're doing, and be able to reproduce it exactly as you're seeing it. stackoverflow.com/help/mcve Commented Nov 16, 2019 at 1:18
  • You are correct, i was trying to keep things simple and in doing so, i missed the line causing the problem all together. Updating now to reflect this. Commented Nov 16, 2019 at 1:25

1 Answer 1

2

You're making the mistake of trying to use the functions SDK to query the database. This is not actually creating a database reference:

functions.database.ref(`count/${request.body.chatRoomId}`);

The functions SDK is just used for declaring and configuring Cloud Functions.

What you should be doing instead is using the Admin SDK to create a reference, then query it:

admin.database().ref(...).once(...)

You also need to initialize the Admin SDK exactly once before you use it:

admin.initializeApp();
Sign up to request clarification or add additional context in comments.

5 Comments

If you look further down in my question, i did attempt to reference the database with the admin SDK via admin.database() which results in the same error noted. I am initializing the application as well at the start of my index.ts via admin.initializeApp(); ill update the question.
CORRECTION: when using the admin SDK the error is different. TypeError: Cannot read property 'ServerValue' of undefined at dbRef.once.then (/srv/lib/index.js:476:51) i will update to reflect this.
The code you shared doesn't use ServerValue, but my guess is that you're using the wrong syntax. It should look like admin.database.ServerValue.TIMESTAMP.
Ah! i had removed several fields from the code in an attempt to keep things short ... in addition to the one field i noted, i was also attempting to write additional fields including a timestamp to the database via updated: admin.database().database.ServerValue.TIMESTAMP i will try removing this field all together to see what happens
I realize thank you's are discouraged, but if you both had not taken the time to respond, i might not have solved this, so thank you. I will update the post to reflect this and mark this as the answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.