Reputation: 3357
I'm following Firebase's instructions and my functions is as follows:
import { DataSource, DataSourceConfig } from "apollo-datasource";
import { KeyValueCache } from "apollo-server-caching";
import firebase from "firebase";
import admin from "firebase-admin";
import "@firebase/firestore";
import { Request } from "apollo-server-env";
export class FirebaseDataSource<TContext = any> extends DataSource {
context!: TContext;
db: firebase.firestore.Firestore;
constructor({
firebaseConfig,
serviceAccount,
databaseURL,
}: {
serviceAccount: any;
firebaseConfig: firebase.app.App;
databaseURL: string;
}) {
super();
this.context;
if (!firebase.apps.length) {
firebase.initializeApp(firebaseConfig);
}
if (!admin.apps.length) {
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL,
});
}
if (!this.db) {
this.db = firebase.firestore();
}
}
async initialize(config: DataSourceConfig<TContext & { request: Request }>) {
this.context = config.context;
}
async user_updateRestaurantFavorites(data: {
uid: string;
someId: string;
add: boolean;
}) {
const collectionRef = this.db.collection("users");
const documentRef = collectionRef.doc(data.uid);
let favorites;
if (data.add) {
favorites = await documentRef.update({
favorites: admin.firestore.FieldValue.arrayUnion(
data.someId
),
});
} else {
favorites = await documentRef.update({
favorites: admin.firestore.FieldValue.arrayRemove(
data.someId
),
});
}
return favorites;
}
}
export default FirebaseDataSource;
I dubugged it and I do pass the uid
, add
, and someId
correctly.
someId
is a string and add
is a boolean (true)
When I run this, I get:
Firestore Function DocumentReference.update() called with invalid data. Unsupported field value: a custom object (found in field favorites in document users/XXXXXXX)
I am just running their own function with a simple string.
Below is an image of my firestore showing the user record does indeed have an empty array ready to accept strings
Upvotes: 1
Views: 3456
Reputation: 9850
It simply means that you need to send exact data which was received by the query. Partial object not allowed
db.collection("users").where("name", "==", somename).limit(1).get().then(query => {
console.log(query);
const thing = query.docs[0];
console.log(thing.data());
let tmp = thing.data();
tmp.current_game_play = tmp.current_game_play + 1;
console.log(tmp);
thing.ref.update(tmp);
});
Upvotes: 0
Reputation: 317487
You're mixing up the web client and admin client SDKs. You can't use the FieldValue
objects exported by firebase-admin when calling methods exported by firebase. The error message is coming from the web client SDK, and it's effectively telling you that you passed an object that it doesn't understand (from the Admin SDK).
You should pick one or the other, and completely remove the one you aren't using in order to avoid problems. If this runs on a backend, you should only use the Firebase Admin SDK, and skip the web client altogether. If you do this, you will need to assign this.db
using the admin SDK, probably as this.db = admin.firestore()
.
Upvotes: 1
Reputation: 4728
Firebase can only store primitive types, maps and array of same. In your case you are saving the result of admin.firestore.FieldValue.arrayUnion(...)
for the property favorites
.
My guess is that the result is not returning a supported type. I have not used FieldValue
before ... is that the correct way to use the API?
Upvotes: 0