11

I'm building a basic CRUD app with vue.js and firebase. I'm trying to build out a favorites functionality and have ran into a persistent problem storing the data.

When a using clicks the add to favorites button I'm attempting to add the document id to an array in a "user profile" document. Here's the code:

export function addNewUserAction (type, key, userID){
  console.log(userID);
  console.log(key);

  firebase.firestore().collection('userActions').add({
    type: type,
    listing: key,
    user: userID,
    time: Date.now()
  })
  if(type === 'favorite'){
    var sendfav = db.collection('userProfiles').doc(userID).update({
      favs: firebase.firestore.FieldValue.arrayUnion(key)
    });
  }else if(type === 'xout'){
    var sendxout = db.collection('userProfiles').doc(userID).update({
      xouts: firebase.firestore.FieldValue.arrayUnion(key)
    });
  }else{
    console.error(type + " is not a user action");
  }
}

I get the following error in the console:

Uncaught TypeError: Cannot read property 'arrayUnion' of undefined
    at addNewUserAction

I have firebase and the db ref imported, and have ran a bogus .set() through each reference to confirm they are pointing at the right spots. I also already have the arrays created in 'userProfile' document.

The firebase install is fresh, like last week fresh, so I should have the function in my build.

Seems that arrayUnion is just not working. Any ideas? The other firestore functions are workin so I'm not sure. Am I blatenly missing something? Thanks

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Tjb1187
  • 161
  • 1
  • 2
  • 9
  • Hey Tjb. It seems that `firebase.firestore.FieldValue` is `undefined`. Can you show exactly how you include Firebase in your code? I'd just like to make sure that you have the right version. – Frank van Puffelen Sep 08 '18 at 00:38
  • Thanks Frank. I am initializing firebase in a component in Vue using the initializeApp function and feeding my apologies keys, project name, etc , then I import firebase into the components that use it. I will admit though that I am a bit confused on how to initialize because I have installed firebase into the Vue app. Should I still be including the CDN scripts in my index.html file? – Tjb1187 Sep 08 '18 at 15:08
  • Also, just checked my package.json file and it says firebase/firestore version=0.7.1 if that's helpful. – Tjb1187 Sep 08 '18 at 16:16
  • Please update your question to include the minimum package.json and/or HTML needed to reproduce the problem. But 0.7.1 sounds like an unusual version to me. As far as I know, the most recent versions are 5.x or 6.x. – Frank van Puffelen Sep 08 '18 at 22:24
  • Hi Frank, sorry for the delayed response. Here is what my package.json has for firebase: `"dependencies": { "firebase": "^5.4.1", "vue": "^2.5.11", "vue-router": "^3.0.1", "vuefire": "^1.4.5" },` – Tjb1187 Sep 23 '18 at 17:05

5 Answers5

15

If you are using the Admin SDK

I was having some random errors similar to this, among others as I was experimenting. It turns out it was because I was using firebase admin sdk which requires a slight change compared to the web SDK documentation. If you are using firebase admin, replace

firebase.firestore.FieldValue.arrayUnion(...

with

admin.firestore.FieldValue.arrayUnion(...

Matthew Rideout
  • 7,330
  • 2
  • 42
  • 61
  • 1
    haha thanks, I feel stupid for not catching this but glad I am not the only person with this issue – Eric Kim Jan 22 '19 at 00:56
  • 1
    Yeah this stuff is a bit confusing. It's so similar that the documentation doesn't seem to bother with it, and yet how would you know? :-) – Rob Grant Oct 25 '20 at 08:24
10

I had the same issue...

This would not work

import { fireStore } from '../../firebase';
....
fireStore.collection("users").doc(props.uid).update({
    points: fireStore.FieldValue.arrayUnion({value: pointObj.value, reason: pointObj.reason})
});

I changed the import and used the exact code from the Firebase Docs.
This works fine.

import * as firebase from 'firebase';
....
fireStore.collection("users").doc(props.uid).update({
    points: firebase.firestore.FieldValue.arrayUnion({value: pointObj.value, reason: pointObj.reason})
});

Hope that helps.

DoubleTri
  • 861
  • 1
  • 7
  • 14
  • I had the same problem. I spent an hour trying to figure out what was wrong. Thanks to your help it works now..... – Ross Nov 19 '18 at 23:21
  • I was importing firebase from another file ex) 'firebase.js'. With this kept, adding line import * as firebase from 'firebase' solved the problem – Inyoung Kim 김인영 Oct 27 '19 at 16:40
5

Just wanted to update this. I was able to get this working by importing firebase the following way:

`import firebase from "firebase/firebase";`

I think my issue before was several problems, the first primarily was not having the correct version. I just recently updated to 5.8.4 which completely broke my app. I tried the above as a possible solution and it got my app working again. That led me to try it on with arrayUnion and it worked. Hopefully thats helpful to someone. Thanks all for the help.

Update 10/11/19 So I wanted to add another update to this in case someone new to firebase is chasing their tail with this as I have been.

So the solution I included above works because it uses the entire firebase SDK package ('firebase/firebase') which is fine, however you will importing the entire firebase package which is not ideal. You constantly see an alert in your console that you're using the development SDK

If you're trying to optimize your app and only import the firebase packages you need ( i.e. auth, datatbase, etc.) you need to import the firebase app object from 'firebase/app' then import the required packages. The key is to import as an object as the firebase docs call for:

import * as firebase from 'firebase/app'; Import 'firebase/auth'

If you use:

import firebase from 'firebase/app' this will not work.

Hope that helps someone. I know it's probie stuff but it stumped me for a while in my learning curve.

Tjb1187
  • 161
  • 1
  • 2
  • 9
0

Firestore - Pass Array To arrayUnion()

let myArray = ["1", "2", "3"];

docRef.update({
    test: firebase.firestore.FieldValue.arrayUnion.apply(this, myArray)
});

This worked for me^

Amacelia
  • 105
  • 10
0

For Vue.js Developers

I have created a folder named firebase in src folder, then i have created a file named init.js in firebase folder

init.js

import * as firebase from "firebase/app";
import "firebase/auth";
import "firebase/firestore";

// For Firebase JS SDK v7.20.0 and later, measurementId is optional
const firebaseConfig = {
  // Your Firebase Config
};

// Initialize Firebase
firebase.initializeApp(firebaseConfig);

// utils
const db = firebase.firestore();
const auth = firebase.auth();

export { db, auth, firebase };

Now use them in whichever components you need. Just by,

import { firebase, auth, db } from "@/firebase/init.js";

Now You can use firebase without any Errors

db.collection("users") // Collection Name
.doc(userId)           // Document in Collection indexed userId
.update({
    friends: firebase.firestore.FieldValue.arrayUnion(auth.currentUser.uid)
})
// friends is the array collection in firestore

Thats It