Karel Debedts
Karel Debedts

Reputation: 5758

Firebase cloud functions: undefined is not a function

I'm trying to convert a map to an array with a firebase cloud functions

This is my code.

  let map = new Map();
  map.set("1", 1);
  map.set("2", 2);
  console.log(new Array(...map).map(pairs => pairs[0]));

  // Upper code not relevant: just to test, but prints ["1", "2"] in the firebase logs)


  const getUser = await admin.firestore()
  .collection("users")
  .doc(context.auth.uid)
  .get();

  let userMap = getUser.data()['friendsMap'];
  console.log(userMap);

   // Prints this in the firebase logs: { '1234ab': 'Jeff',
  5678ab: 'Bob' }


  let userIDLIST = new Array(...userMap).map(pairs => pairs[0]);

  console.log('userIDLIST:'+userIDLIST);

when I want to convert the userMap to userIDLIST array (last lines of code), I get the error:

Unhandled error TypeError: undefined is not a function

What am I doing wrong?

Thanks in advance!

Upvotes: 0

Views: 1639

Answers (1)

Renaud Tarnec
Renaud Tarnec

Reputation: 83048

It is difficult to exactly say what is your problem based on the error you get (which is not really meaningful! :-) ) but it is probably caused by the fact that userMap is not an iterable.

As you will read in the doc (Section "Only for iterables" at the bottom of the page):

Spread syntax (other than in the case of spread properties) can be applied only to iterable objects.

You can check that userMap is not an iterable with the function you will find in the following SO answer.

The reason is that the Map type in Firestore "represents an object embedded within a document" (as explained in the documentation on data Types) and this Object is actually not a Map stricto sensu, but simply an Object.

As explained in the Map doc (Section "Objects vs. Maps"):

Object is similar to Map: both let you set keys to values, retrieve those values, delete keys, and detect whether something is stored at a key. For this reason (and because there were no built- in alternatives), Objects have been used as Maps historically.

However, there are important differences that make Map preferable in certain cases:

.....

  • A Map is an iterable, so it can be directly iterated
  • Iterating over an Object requires obtaining its keys in some fashion and iterating over them.

You can check that userMap is actually not a Map by doing

console.log(userMap instanceof Map);   //  -> False

So, using Object.entries() as follows should solve the problem:

  const getUser = await admin.firestore()
  .collection("users")
  .doc(context.auth.uid)
  .get();

  const userFriendsMap = getUser.data().friendsMap;
  const userFriendsArray = Object.entries(userMap);

  const userIDLIST = new Array(...userFriendsArray).map(pairs => pairs[0]);

Upvotes: 1

Related Questions