-3

A 'days' node with more than 1 child isn't getting removed. How can I fix this issue?

Here's my code below (originally from here):

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
const defaultDatabase = admin.database();

exports.deleteOldItems = functions.database.ref('/path/to/items/{pushId}')
.onWrite(event => {
  var ref = event.data.ref.parent; // reference to the items
  var now = Date.now();
  var cutoff = now - 2 * 60 * 60 * 1000;
  var oldItemsQuery = ref.orderByChild('timestamp').endAt(cutoff);
  return oldItemsQuery.once('value', function(snapshot) {
    // create a map with all children that need to be removed
    var updates = {};
    snapshot.forEach(function(child) {
      updates[child.key] = null
    });
    // execute all updates in one go and return the result to end the function
    return ref.update(updates);
  }).then(function() {;

    const theRef = event.data.ref;
    const collectionRef = theRef.parent.child('days');
    return collectionRef;
    collectionRef.once('value').then(messagesData => {
        if(messagesData.numChildren() > 1) {

  let updates = {};
updates['/days'] = null;
return defaultDatabase.ref().update(updates); // 'days' doesn't get removed even if it has more than 1 child (as in the image)!
        }
    })
});

});

Data structure:

enter image description here

  • You're not returning anything from your last `then()`. Michael showed you how to do this in his answer to [your previous question](https://stackoverflow.com/q/44810960). I recommend learning a bit more about Promises in [this documentation](https://firebase.google.com/docs/functions/terminate-functions), [this video](https://www.youtube.com/watch?v=NgZIb6Uwpjc), and [this blog post](https://firebase.googleblog.com/2017/06/keep-your-promises-when-using-cloud.html). – Frank van Puffelen Jun 29 '17 at 20:45
  • @FrankvanPuffelen Where and how should I add a return statement in my code? –  Jun 29 '17 at 20:49
  • @FrankvanPuffelen I added a `return`, still not working. See the updated question. –  Jun 29 '17 at 20:51
  • You need to ensure that your promise bubbles up to the last `then()` on the top-level. So you need another `return` before `collectionRef.once`. – Frank van Puffelen Jun 29 '17 at 20:55
  • @FrankvanPuffelen See the edit. Still not working... –  Jun 29 '17 at 21:01
  • @FrankvanPuffelen An answer & an explanation to where I went wrong would clear up things for me. –  Jun 29 '17 at 21:04
  • @FrankvanPuffelen I saw Jen's video and the documentation, I'm stuck. –  Jun 29 '17 at 21:20
  • @FrankvanPuffelen What do you think? –  Jun 29 '17 at 21:38
  • Your return statement now prevents the `collectionRef.once` from happening. Note that this is basic JavaScript/Firebase interaction and not specific to Cloud Functions. It's great that you're trying to learn a new system, but you need to take one step at a time. This is why I said you should take a few steps back. Run the same code in a browser (such as through jsbin.com), which makes it easier to debug and experiment. Put a breakpoint on every line. Then run the code and watch at every step. Does it do what you think it should do? Is there a step you didn't expect? – Frank van Puffelen Jun 29 '17 at 23:40

1 Answers1

1

To make your code work, just replace the following line :-

return collectionRef;
collectionRef.once('value').then(messagesData => {

with the following :-

return collectionRef.once('value').then(messagesData => {

The reason this works is that the return statement in return collectionRef prevents further code from executing. Instead of that, you must return the promise(action) as is being done in my suggested replacement.

This should solve your problem right now, but as Frank van Puffelen mentioned in his comments, learning the concepts of promises would tremendously help you in the future!

Rohan Stark
  • 2,346
  • 9
  • 16