keved
keved

Reputation: 49

Custom Object for Cloud Firestore in Node.js runs in snapshot.data is not a function error

I'm working on a web application which receives notifications from an Node.js server. I use Firebase Cloud Firestore as database. Both peaces of code are in the same js file and I've initialized my database and Firebase admin correctly (other operations work). I want to save pulled data from the database in a custom object:

// define logentry for user
class LogEntryUser {
  constructor(token, email){
    this.token = token;
    this.email = email;
  }
  getToken(){
    return this.token;
  }
  getEmail(){
    return this.email;
  }
}

// Firebase data converter
logConverterUser = {
  toFirestore: function(logentryuser){
    return {
      token: logentryuser.token,
      email: logentryuser.email
    }
  },
  fromFirestore: function(snapshot, options){
    const data = snapshot.data(options);
    return new LogEntryUser(data.token, data.email)
  }
}

Here is the code for reading the data from the Cloud Firestore:

db.collection("Users").get().then(function(querySnapshot){
      querySnapshot.forEach((doc) => {
        db.collection("Users").doc(doc.id).withConverter(logConverterUser).get().then(function(snapshot){
          // convert to log object and read token
          logentryuser = snapshot.data();
          var registrationToken = logentryuser.getToken();
        });
      });
    });

Running this script runs in an error:

(node:1648) UnhandledPromiseRejectionWarning: TypeError: snapshot.data is not a function at Object.fromFirestore.

I've used the same code in another js project and everything works fine. I have no idea how to solve this problem. Can anyone help me?

Best wishes keved

Upvotes: 1

Views: 570

Answers (2)

keved
keved

Reputation: 49

In a Node.js Server you can use a 'normal' Javascript Object to store the snapshot. The following code solved my problem:

db.collection("Users").get().then(function(querySnapshot){
  querySnapshot.forEach((doc) => {
    db.collection("Users").doc(doc.id).get().then(function(snapshot){
      var user = snapshot.data();
      var registrationToken = user.token;
    });
  });
});

Upvotes: 1

kiranjith
kiranjith

Reputation: 211

For some reason the withConverter method is passing the actual data instead of snapshot into fromFirestore function. Changing fromFirestore as below fixed it for me.

// Firebase data converter
logConverterUser = {
  toFirestore: function(logentryuser){
    return {
      token: logentryuser.token,
      email: logentryuser.email
    }
  },
  fromFirestore: function(snapshot){
    const data = snapshot;
    return new LogEntryUser(data.token, data.email)
  }

Upvotes: 1

Related Questions