I am updating a document in firebase when user enters a comment.The code for the same is:
const docRef=collection(db,"posts",post.id);
console.log(docRef);
updateDoc(docRef,{
user:localStorage.getItem('Name'),
title: post.title,
comment:temppost ,
upVotesCount: 0,
downVotesCount: 0,
createdAt: post.createdAt,
updatedAt: date.toUTCString(),
isCommentVisible:false
});
But I m getting this error:
Uncaught (in promise) FirebaseError: Invalid collection reference. Collection references must have an odd number of segments, but posts/PQAvoGjUeX8aPVVZxMNC has 2.
I haven't used any subcollections here.
You need a DocumentReference to update a single document that you can create using doc(). The collection() is used to create a CollectionReference:
// use doc() instead of collection()
const docRef = doc(db,"posts",post.id);
Also checkout: Firestore: What's the pattern for adding new data in Web v9?
You are trying to pass a document in a collection function. (db,"posts") is how you refer to a collection and (db,"posts",post.id) is how you refer to a document. So use one of these:
const docRef = doc(db,"posts",post.id); // 3 arguments for a document
------
const postsRef = collection(db,"posts"); // 2 arguments for a collection
const docRef = (postsRef,post.id); // in essence 2+1 arguments for a document
Related
I've been working on chrome extention project.
What I am trying to do is store the input value and pull it out when the specific button is pressed.
Below is the part of js code:
import { Dexie } from '../node_modules/dexie/dist/dexie.mjs';
var DBName = 'test';
buttonA.addEventListener('click', () => {
const inp = document.getElementById("inp");
const db = new Dexie(DBName);
db.version(2).stores({
friend: '++id, name'
});
db.friend.add({
name: inp.value
})
});
buttonB.addEventListener('click', () => {
const db = new Dexie(DBName);
const ch = db.friend;
console.log("Checking the value in DB: " + ch);
});
When I try it, it stores whatever input to indexed DB after clicking buttonA (confirmed by using Chrome Developer Tool), however when it comes to clicking on buttonB, the log tells that ch is undefined (same for db.friend.name or db.name as well).
Because of this, even when I use get(), it returns me an error since I am accessing on undefined variable.
Could someone help figuring out why the program does not access properly to an indexed DB that exists when I click on a buttonB?
Thank you.
Problems:
The second instance of Dexie does not declare which tables there are, so db.friend is unknown.
Your code creates a new Dexie for every click. It would be much better and faster to reuse a single Dexie instance. If you create a new Dexie instance everytime, you must also close it after you to avoid resource leakage.
Recommendation:
Declare a singleton Dexie instance with version().stores(...) so it populates the 'friend' property for you.
Preferably this code could be in it's own module (such as 'db.js').
Use that single Dexie instance from any place where you need to store or read from the db.
New to MongoDB, very new to Atlas. I'm trying to set up a trigger such that it reads all the data from a collection named Config. This is my attempt:
exports = function(changeEvent) {
const mongodb = context.services.get("Cluster0");
const db = mongodb.db("TestDB");
var collection = db.collection("Config");
config_docs = collection.find().toArray();
console.log(JSON.stringify(config_docs));
}
the function is part of an automatically created realm application called Triggers_RealmApp, which has Cluster0 as a named linked data source. When I go into Collections in Cluster0, TestDB.Config is one of the collections.
Some notes:
it's not throwing an error, but simply returning {}.
When I change context.services.get("Cluster0"); to something else, it throws an error
When I change "TestDB" to a db that doesnt exist, or "Config" to a collection which doesn't exist, I get the same output; {}
I've tried creating new Realm apps, manually creating services, creating new databases and new collections, etc. I keep bumping into the same issue.
The mongo docs reference promises and awaits, which I haven't seen in any examples (link). I tried experimenting with that a bit and got nowhere. From what I can tell, what I've already done is the typical way of doing it.
Images:
Collection:
Linked Data Source:
I ended up taking it up with MongoDB directly, .find() is asynchronous and I was handling it incorrectly. Here is the reply straight from the horses mouth:
As I understand it, you are not getting your expected results from the query you posted above. I know it can be confusing when you are just starting out with a new technology and can't get something to work!
The issue is that the collection.find() function is an asynchronous function. That means it sends out the request but does not wait for the reply before continuing. Instead, it returns a Promise, which is an object that describes the current status of the operation. Since a Promise really isn't an array, your statment collection.find().toArray() is returning an empty object. You write this empty object to the console.log and end your function, probably before the asynchronous call even returns with your data.
There are a couple of ways to deal with this. The first is to make your function an async function and use the await operator to tell your function to wait for the collection.find() function to return before continuing.
exports = async function(changeEvent) {
const mongodb = context.services.get("Cluster0");
const db = mongodb.db("TestDB");
var collection = db.collection("Config");
config_docs = await collection.find().toArray();
console.log(JSON.stringify(config_docs));
};
Notice the async keyword on the first line, and the await keyword on the second to last line.
The second method is to use the .then function to process the results when they return:
exports = function(changeEvent) {
const mongodb = context.services.get("Cluster0");
const db = mongodb.db("TestDB");
var collection = db.collection("Config");
collection.find().toArray().then(config_docs => {
console.log(JSON.stringify(config_docs));
});
};
The connection has to be a connection to the primary replica set and the user log in credentials are of a admin level user (needs to have a permission of cluster admin)
i want to add a reference field in a document into Firestore using nodejs but i can't do it.
I wrote this code:
async function pushType(IDType) {
const size = await getID();
const IDClient = (size).toString();
const docRef = firebase.firestore().collection('Clients').doc(IDClient);
await docRef.set({
ID_Type: firebase.firestore().doc('Types/'+IDType).ref,
});
}
async function getID(){
const snapshot = await firebase.firestore().collection('Clients').get();
return snapshot.size;
}
The error is: "Function Document.Reference.set() called with invalid data. Unsupported field value: undefined (found in field ID_Type in document Clients/7)" where 7 is the ID of the document where i want to add the field ID_Type.
Can anyone help me to understand what i'm wrong and how can i fix it? Thank you
Your code firebase.firestore().doc('Types/'+IDType) returns a DocumentReference. As you can see from the API docs, there is no property called ref on that, so it will be undefined. In fact, that DocumentReference is exactly what you want to provide to Firestore here. So just remove ref:
await docRef.set({
ID_Type: firebase.firestore().doc('Types/'+IDType)
});
When you provide a DocumentReference object to a Firestore document like this, it will create a reference type field.
I am not able to pull data on collection, getting this error
Uncaught TypeError: doc.data is not a function
var db = firebase.firestore();
const docRef = db.collection("Slides");
getRealData = function() {
docRef.onSnapshot(function(doc) {
const myData = doc.data();
console.log(myData);
});
};
getRealData();
I find the solution if I pass fix id then below code work
(Although ID are random generate by firestore)
db.collection("Slides").doc("GYUzWG6jcOPob725wbnF")
.onSnapshot(function(doc) {
console.log("Current data: ", doc.data());
});
Firestore
In your first code sample, you're assuming that the snapshot callback attached to this:
db.collection("Slides")
Is similar to the one attached to this:
db.collection("Slides").doc("GYUzWG6jcOPob725wbnF")
In fact, they are not the same at all.
The first one will query for ALL the documents in the named collection, and it will give you a QuerySnapshot object in the callback. This object does not have a data() method, and you need to iterate it to get all the document snapshots.
The second one will query for only the named document in the named collection, and you will get a DocumentSnapshot object back.
Since you didn't say what you're trying to accomplish, I can't recommend what you should be doing. All I can say is that the two code bits you've shown are not at all alike, and you'd expect them to behave differently.
By the error message looks like data is not a function, it mean that you don't have to use parentheses when assigning it to variable, so change your assignment to this line:
const myData = doc.data;
Actually, my approach was wrong, use get function to get all the data.
docRef.get().then(function(querySnapshot) {
querySnapshot.forEach(function(doc) {
// doc.data() is never undefined for query doc snapshots
console.log(doc.id, " => ", doc.data());
});
});
Ok, I have looked at similar questions like Firebase function onWrite not being called and thought it was my fault getting the reference, but I have no idea what is happening here with my Firebase functions.
I am just trying to get a function to write to my database when a write has been made to database. I followed the firebase tutorial exactly:
const functions = require('firebase-functions');
// The Firebase Admin SDK to access the Firebase Realtime Database.
//https://firebase.google.com/docs/functions/database-events
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
// const gl = require('getlocation');
exports.helloWorld = functions.https.onRequest((request, response) => {
response.send("Hello from Firebase!");
});
exports.enterLocation = functions.database.ref('/Users/{name}') //brackets is client param
.onWrite(event => {
// Grab the current value of what was written to the Realtime Database.
// const original = event.data.val();
console.log('SKYLAR HERE:', event.params.name);
// You must return a Promise when performing asynchronous tasks inside a Functions such as
return firebase.database().ref('/Users/{name}').set({ location: 'test loc' });
});
The function is being run, yet in my logs I get a pretty unhelpful error that it is getting the {name} param, and data is definitely written to my database, however my SERVER code is not writing:
I get -
ReferenceError: firebase is not defined at
exports.enterLocation.functions.database.ref
Which makes no sense as it is defined. I just want to add an extra child under the user I create, like I do already with "password"
What am I doing wrong?
Two problems here. First, you haven't defined firebase anywhere in your code. I think you meant to use admin instead to use the Admin SDK.
Second, it looks like you're trying to do variable interpolation into a string to build the name of the ref. Your syntax is wrong here.
I imagine you're trying to say this instead in your last line of code:
return admin.database().ref(`/Users/${name}`).set({ location: 'test loc' });
Note the backticks on the string quotes. That JavaScript syntax lets you use ${exp} to insert the contents of some expression in the string.
It turns out you don't even need to use the admin SDK here. Since you're trying to write back to the same location that triggered the function, you can just use the ref that comes from the event object:
return event.data.adminRef.set({ location: 'test loc' });
instead of this:
return firebase.database().ref('/Users/{name}').set({ location: 'test loc' });
use this:
return admin.database().ref('/Users/{name}').set({ location: 'test loc' });