read messages from realtime databse in firebase with javascript - javascript

i want to read messagea from realtime database in firebase with vue or javascript in quasar framework
my collection name in db is messages that have this strtucture:
******************************************* my db structure*******
messages
-N4zbIt0Ey6Bix54f5SE
content: "Hi"
fromId: "nTTcnND2y6OHUBVO2GxHoBFwQf32"
timestamp: 1655703420767
toId: "0FXpksPdL4OAf9KAXx9B0R6nzmh2"
type: 1
-N4zbIt0Ey6Bix54f5SE
content: "Hi,HOW ARE YOU"
fromId: "0FXpksPdL4OAf9KAXx9B0R6nzmh2"
timestamp: 1655703448111
toId: "nTTcnND2y6OHUBVO2GxHoBFwQf32"
type: 1
do you know how i query firebase to getmessages?? ithis is for save in state with Vuex
firebaseGetMessages({ commit, state }, otherUserId) {
let userId = state.userDetails.userId
messagesRef = firebaseDb.ref('messages/' + fromId + '/' + toId)
messagesRef.on('child_added', snapshot => {
let messageDetails = snapshot.val()
let messageId = snapshot.key
commit('addMessage', {
messageId,
messageDetails
})
})
i think this code is wrong
please help me if you have any experince with firebase
i am not familar with realtime-databse and query in fcm
but familar with mongodb and sql server database
i think that firebase has some function to read message!!! is it n't???

Your code indeed does not match the data structure that you shared.
Your code expects this structure:
messages: {
"uidOfSender": {
"uidOfRecipient": {
...
}
}
}
While your data structure has the UIDs of the sender and receiver as properties on each message in a flat list.
Worse: there is no way to get the messages between a sender and receiver from your current structure, as Firebase Realtime Database queries can only filter on one property. See my answer here for more on that: Query based on multiple where clauses in Firebase
The data structure in general looks like a 1:1 translation of what you'd do in a relation database, which is often not a great starting point when modeling data for a NoSQL database. What you'll want to do is create a different data structure where you set up a sort-of "chat room" for each pair of users, as I've shown here: Best way to manage Chat channels in Firebase
I also recommend reading NoSQL data modeling and watching Firebase for SQL developers.

Related

Firebase v9 - Get a Referentiated Document Content

I don't understand why I'm not finding this documentation anywhere.
But I have a collection called users in my Firebase Firestore project. Inside users there are three collections: companies, policies and stores.
In the collection policies I have one store field and one company field that are references to one of that user's store or company.
Ok so as far as now is fine. But now, I'm performing the next query:
const subcollectionSnapshot = await getDocs(collection(db, 'users', 'S3casIyXxdddEAaa1YJL6UjBXLy2', 'policies'));
And the response is the next one:
But now... how can I get the company and store nested documents? How can I "populate" them in order to see their information and access their fields?
Thanks.
It looks like the company and store fields are of type DocumentReference.
In that case you can get a DocumentSnapshot of each of them by calling getDoc() with the DocumentReference:
subcollectionSnapshot.docs.forEach((policyDoc) => {
const companyRef = policyDoc.data()["company"];
const companyDoc = await getDoc(companyRef);
const storeRef = policyDoc.data()["store"];
const storeDoc = await getDoc(storeRef);
...
})
If you have multiple policy documents, you will need to do this for each of them. There is no concept of a server-side join in Firestore (nor in most other NoSQL databases).

Query stored values that contain specific string

I have a small realtime firebase database that's set up like this:
database
-messages
--XXXXXXXXXXXX
---id : "XXX-XXX"
---content : "Hello world!"
It's a very simple message system, the id field is basically a combination of users id from my mysql database. I'm trying to return all messages that match one of the ids, either sender or receiver. But I can't do it, seems like firebase only support exacts querys. Could you give me some guidanse?
Here's the code I'm working with
firebase.database().ref("messages").orderByChild("id").equalTo(userId).on("value", function(snapshot)
I'm looking for something like ".contains(userId)"
Firebase supports exact matches (with equalTo) and so-called prefix queries where the value starts with a certain value (by combining startAt and endAt). It does not support querying for values that end with a certain value.
I recommend keeping a mapping from each user IDs to their messages nodes, somewhere separately in their database.
So say that you have:
messages: {
"XXXXXXXXXXXX": {
id : "YYY-ZZZ",
content : "Hello world!"
}
}
You also have the following mappings:
userMessages: {
"YYY": {
"XXXXXXXXXXXX": true
},
"ZZZ": {
"XXXXXXXXXXXX": true
}
}
Now with this information you can look up the messages for each user based on their ID.
For more on the modeling of this type of data, I recommend:
Best way to manage Chat channels in Firebase
Many to Many relationship in Firebase
this artcle on NoSQL data modeling

Search with array in firebase realtime database

Is there any way to search with array in realtime database as cloud database provides us.
Cloud example:
.collection("bids")
.where("title", "array-contains-any", ["xx", "yy", "zz"])
In above query I got all bids where title is xx, yy, zz.
How do we can search like this in firebase realtime database.
Actually in real-time database there is no any thing like "array-contains". There for if you have an array you have to deal with just like a regular JavaScript array.
In your case you can try this.
var ref = firebase.database().ref('/bids/title');
ref.once('value').then(function(snap) {
var array = snap.val();
for (var i in array) {
var value = array[i]
console.log(value);
if (value == 'xx') { ... }
}
});
There is no equivalent operation in the Realtime Database.
The common approach for this type of use-case, is to set up an additional data structure mapping from bid titles to bids as shown here: Firebase query if child of child contains a value
You can then read the bid IDs for each title with a separate query, look up the additional properties for each bid with another call, and then merge all results in your client-side application code. This is not nearly as slow as you may initially expect, as Firebase pipelines the requests over a single websocket connection.
Nowadays, in Firebase's real-time database, you don't have to do that anymore! These ugly codes to save arrays nowadays are left behind, try to use the module: Fireray.
These codes make Firebase references very ugly, for example:
"dir": {
"arrays": {
"users": {
"0": {},
"1": {},
"2": {}
}
},
"others": {}
}
It is a Brazilian module, but there is a documentation in English. Give her a chance, she's really very good!
Links:
Npm package
Documentation in English
Repository
Programmer
Sincerely: Lucas

Write an object containing an array of objects to a mongo database in Meteor

In my user collection, I have an object that contains an array of contacts.
The object definition is below.
How can this entire object, with the full array of contacts, be written to the user database in Meteor from the server, ideally in a single command?
I have spent considerable time reading the mongo docs and meteor docs, but can't get this to work.
I have also tried a large number of different commands and approaches using both the whole object and iterating through the component parts to try to achieve this, unsuccessfully. Here is an (unsuccessful) example that attempts to write the entire contacts object using $set:
Meteor.users.update({ _id: this.userId }, {$set: { 'Contacts': contacts}});
Thank you.
Object definition (this is a field within the user collection):
"Contacts" : {
"contactInfo" : [
{
"phoneMobile" : "1234567890",
"lastName" : "Johnny"
"firstName" : "Appleseed"
}
]
}
This update should absolutely work. What I suspect is happening is that you're not publishing the Contacts data back to the client because Meteor doesn't publish every key in the current user document automatically. So your update is working and saving data to mongo but you're not seeing it back on the client. You can check this by doing meteor mongo on the command line then inspecting the user document in question.
Try:
server:
Meteor.publish('me',function(){
if (this.userId) return Meteor.users.find(this.userId, { fields: { profile: 1, Contacts: 1 }});
this.ready();
});
client:
Meteor.subscribe('me');
The command above is correct. The issue is schema verification. Simple Schema was defeating the ability to write to the database while running 'in the background'. It doesn't produce an error, it just fails to produce the expected outcome.

firebase simple - data structure questions

I have been reading a little about how to structure your firebase database and i understand that you need to split your data into pieces so you don't forced the client to download all of the 'users' data.
So in this example you will get all the users data when you write
ref.('users').once('value', function(snap)...
/users/uid
/users/uid/email
/users/uid/messages
/users/uid/widgets
but what if you specifically write the path to the location instead like
ref.('users/uid/email').once('value', function(snap)...
Will you still get all the users data or only the data in email ?
In firebase, you set the ref to be the reference for your database (the whole database) and then you got methods to iterate through each piece of data of your database object, hence, a good practice is to set all your database as the ref and then work from there to go through what you want to go.
// will select the whole db
const firebaseRef = firebase.database().ref();
// will select the whole app object of your db
const firebaseRef = firebase.database().ref().child('app');
// will select the whole users object of your db
const firebaseRef = firebase.database().ref().child('app/users');
So, it is a good practice to set a variable like firebaseRef to be your whole firebase db and then iterate from there.
Now, if you write:
firebaseRef.child(`users/${uid}/email`).once('value').then(snapshot => {
console.log('User email: ', snapshot.val());
}, e => {
console.log('Unable to fetch value');
});
Yes, you will get what you're asking, but you need to use the child method to get to the objects of your firebase ref.

Categories