Is it possible to get document id of collections available in Firebase Cloud Firestore database? - javascript

I want to get the document id of societies collection in cities collection but my code returns a different id in societyId field in the cities collection.
myId: string = "";
private docRef: firebase.firestore.DocumentReference;
this.docRef = firebase.firestore().collection("societies").doc();
this.myId = this.docRef.id;
this.cityList = firebase.firestore().collection("cities").add({
cityName: this.city,
societyId: this.myId
}).then((doc) => {
console.log(doc);
}).catch((err) => {
console.log(err);
});

You are getting another societyId, which is different than the id that is generated by simply calling doc() function because you are adding an object to the database using CollectionReference's add() function:
Adds a new document to this collection with the specified data, assigning it a document ID automatically.
Instead of using DocumentReference's set() function:
Writes to the document referred to by this DocumentReference. If the document does not exist yet, it will be created. If you pass options, the provided data can be merged into the existing document.
According to your comment, if you want to have the same id, please change the following line of code:
this.cityList = firebase.firestore().collection("cities").add(/* ... */);
to
this.cityList = firebase.firestore().collection("cities").doc(this.myId).set(/* ... */);

Related

Store documentId as field in document

I want to store the documentId created in collection as the field/property as docid in the same document. I am using cloud firestore.
It is showing error "ReferenceError: doc is not defined"
whenever I try and store the doc.id
db.collection("Colleges").doc(user.uid).collection('Internships').doc().set({
CompanyName :this.I_company,
InternshipTitle : this.I_title,
duration: this.duration,
amount:this.I_amount,
week:this.week,
docid: doc.id
})
Indeed, a call to the doc() method of a CollectionReference without any path will return a DocumentReference with "an automatically-generated unique ID".
But you have to do as follows: first get the new DocumentReference, then use the set() method on this DocumentReference.
var docRef = db.collection("Colleges").doc(user.uid).collection('Internships').doc();
docRef.set({
CompanyName :this.I_company,
InternshipTitle : this.I_title,
duration: this.duration,
amount:this.I_amount,
week:this.week,
docid: docRef.id
})
However, you may double check if you really need to write the docRef.id in a specific field of the document, because in any case you can get it later with the id property.

mongo db query check that no other document with matched values exist

I want to create a query with which I can check if a document has related documents, e.g. I have a document
{
name:"test1",
status:"CREATED"
date:"2018-12-12"
user:"foo"
}
and i want to retreive all documents where the user has no document with status:"OPEN"
I had the idea to project a field with the number of documents which are open for the user & day and filter for 0, but I don't know how I could do that.
So when i have the following documents:
it should only return foo2 and foo4 because foo, foo3 and foo5 already have documents with status:"OPEN"
Please find the below code to get all the documents for users for whom no 'OPEN' status exists:
db.collection.find({
user: {
$nin: db.collection.find({status: 'OPEN'}).map((row) => row.user)
}
});
$nin: to specify and exclusion list.
.map((row) => row.user): to convert array of filtered documents to array of just the string containing user ids.
Here is the logic:
1.First query all the doc with status OPEN
2.Now you have a sets of data with OPEN only doc
4.Now create a query where you pass all the userId of this set in query and fetch those values from collection which have userId not equal to the passed ones
Example:
db.collectionName.find({status:'OPEN'});// set1
db.collectionName.find({userId:{$not : 'userid1'}},{userId:{$not : 'userid2'}},....);
This is not good code but this is all you can do now or add some other fields in db to do it more effectively

How to get firebase id

Anyone know how to get the Firebase unique id? I've tried name(), name, key, key(). Nothing works.
I am able to see the data but I have no idea how to get the id back. I need it.
//Create new customers into firebase
function saveCustomer(email) {
firebase.database().ref('/customers').push({
email: email
});
firebase.database().ref('/customers').on("value", function(snapshot) {
console.log(snapshot.val());
console.log(snapshot.value.name());
}, function(errorObject) {
console.log("The read failed: " + errorObject.code);
});
}
The call to push will return a Firebase reference. If you are using the Firebase 3 API, you can obtain the unique key of the pushed data from the reference's key property:
var pushedRef = firebase.database().ref('/customers').push({ email: email });
console.log(pushedRef.key);
The key for the pushed data is generated on the client - using a timestamp and random data - and is available immediately.
Calling push() will return a reference to the new data path, which you can use to get the value of its ID or set data to it.
The following code will result in the same data as the above example, but now we'll have access to the unique push ID that was generated:
// Generate a reference to a new location and add some data using push()
var newPostRef = postsRef.push();
// Get the unique ID generated by push()
var postID = newPostRef.key();
Documentation.
but this method won't work when you also need the id beforehand
for example to save it in the database itself.
Firebase suggests this:
// Add a new document with a generated id.
var newCityRef = db.collection("cities").doc();
--for some reason, push() and key() didn't work for me. also in this case the reference contains the whole path. so need a different method for getting the id.
Doing this below helped to get the id from the reference and use it.
const ref = db.collection('projects').doc()
console.log(ref.id) // prints the unique id
ref.set({id: ref.id}) // sets the contents of the doc using the id
.then(() => { // fetch the doc again and show its data
ref.get().then(doc => {
console.log(doc.data()) // prints {id: "the unique id"}
})
})

Accessing Firebase push() child

I'm slowly getting into Firebase but have what is probably a stupid question. If I am adding children to a reference using push(), how do I retrieve/delete them if I don't save the generated push ID?
For example, take this root:
var ref = https://myaccount.firebaseio.com/player
And if I write a new entry to /player:
var new_player= ref.push({
name:"User",
country:"United States"
})
Firebase generates a push ID for that:
https://myaccount.firebaseio.com/player/-JxgQCQsSLU0dQuwX0j-
which contains the information I pushed. Now lets say I want to retrieve or remove that player? Should I store the generated ID as a child of itself using .key() and .set()?:
//this will get -JxgQCQsSLU0dQuwX0j-
var _newPlayerKey = new_player.key();
//updates the record I just created
var update_player = ref.set({
name:"User",
country:"United States",
ref: _newPlayerKey
})
I don't see how else to access that object by it's generated ID... is there a better way to set this up?
Why are you doing that can't use the key() method, it should be adequate in almost all cases i.e.
playersRef.limit(10).on('child_added', function (snapshot) {
var player = "<p>"+ snapshot.val().name +" <button data-value='"+snapshot.key()+"'>Delete</button></p>";
$(player).appendTo($('#messagesDiv'));
});

mongo find selector causes unmatching results to be returns

userLink_titles = Entries.find({ _id:"bxSbMgszYxbCqDonF"})
returns:
docs: Object
CBqHrJvTE8xz7u2Rz: Object
_id: "CBqHrJvTE8xz7u2Rz"
author: "AHSwfYgeGmur9oHzu"
Q8m7PMbQr62E3A73f: Object
_id: "Q8m7PMbQr62E3A73f"
author: "AHSwfYgeGmur9oHzu"
bxSbMgszYxbCqDonF: Object
_id: "bxSbMgszYxbCqDonF"
author: "AHSwfYgeGmur9oHzu"
As you can see it returns the correct document but it also returns incorrect documents.
findOne: userLink_titles = Entries.findOne({ _id:"bxSbMgszYxbCqDonF"}) works as expected and only returns the correct document.
I would use the findOne except that the end intention is to make the _id selector an array such that find would return the documents for all documents that match the _id selectors in the array.
Bonus Points:
Let's say I wanted to retrieve the titles of a set of articles, where the references to those articles (the _ids of the Articles in their Articles collection) have been saved in a user collection.
So effectively I would retrieve the Article references from the user collection, and use those references to retrieve the titles of Articles from the Articles collection.
What would the code/pseudo code look like for that? Something like the following (I am assuming the below is a complete bastardization of some best practices for querying/retrieving records)
user_profile = Users.findOne({username : "Frank"});
user_saved_articles_ids = user_profile.findOne({saved_articles_ids});
userLinks = Articles.find({ _id:user_saved_articles_ids});
userLinksTitles = Articles.find({titles});
For those interested in the bonus question, you want MongoDB's $in operator.
If this will be used in a publish method on the server then you may want to check out publish-with-relations.
Something like the function below would be an efficient way to retrieve the information. It makes two calls to the database. Using the fields parameter prevents unnecessary data from being sent between the db and the webserver.
/**
* Titles of a User's saved articles
*
* #method getSavedTitles
* #param {String} username
* #return {Array} a list of article titles
*/
function getSavedTitles (username) {
var user,
ids,
linkedArticles,
titles;
user = Users.findOne({username: username},
{fields:{ _id:0, profile:1 }});
if (!user || !user.profile) {
throw new Meteor.Error(500, 'Missing user profile');
}
ids = user.profile.savedArticleIds;
if (!ids || !_.isArray(ids)) {
throw new Meteor.Error(500, 'Missing saved article ids');
}
linkedArticles = Articles.find({_id: {$in: ids}},
{fields:{ _id:0, title:1 }});
titles = _.pluck(linkedArticles.fetch(), "title");
return titles;
} // end getSavedTitles
If you want to inspect the results of a query in the console, use Entries.find(...).fetch()
Entries.find() returns a cursor, which is a construct used to render lists efficiently, so that only the entries that change need to be re-rendered. Returning cursors from helpers on which you use {{#each}} will lead to more responsive apps.

Categories

Resources