firebase snapshot is not working with node js GCF - javascript

I have a firebase database structure in this format
the database is follows this format Ordergroup/groupid/item
I want to get the buyerid for each item once a new group is created in the ordergroup node. So I try this
exports.sendorderemailtoseller = functions.database.ref('/Ordergroup/{pushId}').onCreate((snapshot, context) => {
const parentRef = snapshot.ref.parent;
const ref = snapshot.ref;
const original = snapshot.val();
const buyerid = original.buyerid;
})
I then notice that original only returns the first child and the buyerid comes out as undefined. How can I get a snapshot of all the child in the groupid excluding Ordersummary?

Your variable 'original' is actually getting the whole tree under node 1522509953304, so you will need to iterate over its children to get each buyerid, like below:
exports.sendorderemailtoseller = functions.database.ref('/Ordergroup/{pushId}').onCreate((snapshot, context) => {
const buyerids = [];
snapshot.forEach((item) => {
buyerids.push(item.val().buyerid);
});
console.log(buyerids);
});

Related

Can't update firebase collection field - Expected type 'ya', but it was: a custom Ia object

I am trying to make barbershop web app where costumer can see list of free appointments and when they reserve free appointment I want to delete that field from firebase.
I have a collection which represents one barber.
This is how it looks in firebase.
As you see radno_vrijeme is object or map in firebase which contains 6 arrays, and in each array there is list of free working hours.
In my function I am able to do everthing except last line where I need to update firebase collection.
const finishReservation = async () => {
try {
const freeTimeRef = collection(db, `${barber}`);
const q = query(freeTimeRef);
const querySnap = await getDoc(q);
querySnap.forEach(async (doc) => {
const radnoVrijeme = doc.data().radno_vrijeme;
// Find the index of the hour you want to delete
const index = radnoVrijeme["Mon"].indexOf(hour);
// Remove the hour from the array
radnoVrijeme["Mon"].splice(index, 1);
// Update the document in the collection
console.log(radnoVrijeme);
const radnoVrijemeMap = new Map(Object.entries(radnoVrijeme));
await freeTimeRef.update({ radno_vrijeme: radnoVrijemeMap });
});
} catch (error) {
console.log(error);
}
};
I tried to pass it as JSON stringified object, but it didn't work. I always get this error :
"FirebaseError: Expected type 'ya', but it was: a custom Ia object"
When you are trying to fetch multiple documents using a collection reference or query, then you must use getDocs():
const finishReservation = async () => {
try {
const freeTimeRef = collection(db, `${barber}`);
const q = query(freeTimeRef);
const querySnap = await getDocs(q);
const updates = [];
querySnap.forEach((d) => {
const radnoVrijeme = d.data().radno_vrijeme;
const index = radnoVrijeme["Mon"].indexOf(hour);
radnoVrijeme["Mon"].splice(index, 1);
const radnoVrijemeMap = new Map(Object.entries(radnoVrijeme));
updates.push(updateDoc(d.ref, { radno_vrijeme: radnoVrijemeMap }))
});
await Promise.all(updates);
console.log("Documents updated")
} catch (error) {
console.log(error);
}
};
getDoc() is used to fetch a single document using a document reference.

merkletreejs method getHexProof return empty string

I'm trying to create a whitelist merkle tree for a NFT collection so I tried this code:
const { MerkleTree } = require('merkletreejs');
const keccak256 = require('keccak256');
const leaves = tab.map((address) => keccak256(address));
const tree = new MerkleTree(leaves, keccak256, { sort: true });
const root = tree.getHexRoot();
const leaf = keccak256('myaddress');
const proof = tree.getHexProof(leaf);
But proof is always empty, why?
PS: leaf look like that when I'm trying to log it: ���_�vD��CT,��sh��+o�j��ߧ
The proof was empty because my address ("myaddress" in the code) was not in the whitelist

Retrieve data using axios and append data to elements created in callback function

I am trying to use axios to retrieve data from a url and then append the data to html elements I created using javascript.
In a nutshell for each programming language in my url I would like to have a card showing the headline and author name of each article.
This is my HTML
<body>
<div class="parentDiv">
</div>
</body>
</html>
and my JS
const CardsTest = (one) => {
// class headline
const divHead = Object.assign(document.createElement('div'), {className: 'one', textContent: one.headline});
// class author
const divAut = Object.assign(document.createElement('div'), {className: 'writer'});
const spanCont = Object.assign(document.createElement('span'), {className: 'name', textContent: one.authorName});
divAut.appendChild(SpanCont);
divHead.appendChild(divAut);
return divHead;
}
const cardAppender = (div) => {
const divOne = document.querySelector(div);
axios.get('http://localhost:5000/api/articles')
.then((resp) => {
Object.keys(resp.data).forEach (
function(obj) {
const topicsData = CardsTest(obj.articles);
divOne.appendChild(obj.articles)
}
)
})
}
cardAppender('parentDiv')
I know that my function CardsTest creates all the components and my cardsappender can, at the very least print out the JSON from the target URL. I know if I run the function with axios and console log obj.articles I get an object promise containing the articles in the URL.
To summarize; I expect cardAppender to take a url, and take a callback function (Cards Test) appending the writer and headline to the elements in Cards Test and then append that to my html parentDiv. However this is not happening
UPDATE
Tried changing my cardAppender function by creating an array of programming languages (the keys in my JSON) and then appending headline and authorname for each article to my Cards Test function, but this function is still not creating the components in Cards Test:
const cardsAppender = (div) => {
const newArr = ["javascript","bootstrap","technology","jquery","node"]
const divOne = document.querySelector('.parentDiv');
axios.get('http://localhost:5000/api/articles')
.then((resp) => {
newArr.forEach((item) => {
const cardsHolds = CardsTest(resp.data.articles[item])
divOne.appendChild(cardsHolds)
})
})
}
cardsAppender('.parentDiv')
You are using Object.keys to iterate, so you need to use that key as a property index. Or use Object.values. It's not really clear what shape your data is though, so this might need to be tweaked.
Object.keys(resp.data).forEach (
function(obj) {
const topicsData = CardsTest(res.data[obj].articles);
divOne.appendChild(res.data[obj].articles)
}
Object.values(resp.data).forEach (
function(obj) {
const topicsData = CardsTest(obj.articles);
divOne.appendChild(obj.articles)
}

Retriving split data from firebase

// how I get the data
db.collection('Pins').get().then(snapshot => {
snapshot.forEach(pinInfo => {
pinsToMap(pinInfo)
});
});
// trying to set the data
function pinsToMap(pinInfo){
let pinName;
let pinCoOrdsLat;
let pinCoOrdsLong;
let pinToMapInfo;
pinName = doc.data().name
pinCoOrds = doc.data().coOrds
pinToMapInfo = doc.data().Info
Pins.child(Pins.coOrds).set({
coOrds: {
0:this = pinCoOrdsLat,
1:this = pinCoOrdsLong,
}
});
}
I am storing data in my database based off a map pin, I am now trying to use the stored data to create a pin on the map of the same place, how do I query out the coOrds in to pinCoOrdsLat / pinCoOrdsLong as this way doesn't seem to be working
If I correctly understand you question, the following should do the trick:
db.collection('Pins').get().then(snapshot => {
snapshot.forEach(pinInfo => {
pinsToMap(pinInfo)
});
});
// trying to set the data
function pinsToMap(pinInfo) { // IMPORTANT! => pinInfo is a DocumentSnapshot
const pinName = pinInfo.data().name
const pinCoOrds = pinInfo.data().coOrds
const pinToMapInfo = pinInfo.data().Info
//pinCoOrds is a JavaScript Array with two elements
const pinCoOrdsLat = pinCoOrds[0];
const pinCoOrdsLong = pinCoOrds[1];
//Use pinCoOrdsLat and pinCoOrdsLong the way you want, e.g. calling a leaflet method
}
You'll find here the doc for a DocumentSnapshot

Reading data from Firebase Array-Like

I have a model in Firebase, who is saved like this:
Im fetching the data in my componentDidMount like this:
fetchMatches = async () => {
const { firebaseApp, auth, pool } = this.props;
await firebaseApp.database()
.ref(`/pools/${pool.key}/users/${auth.uid}/`)
.once('value')
.then(snapshot =>{
this.setState({matches:snapshot.val()})
})
}
The problem is, that my state, becomes an object: Not an Array, not a list.
How can I read this data, in a proper way that I can filter it based on an atribute.
When I try to do
let matches = this.state.matches;
for (let index = 0; index < matches.length; index++) {
const element = matches[index];
console.log(element);
}
It not works.
When I try to use a this.state.matches.map() they say that is not a function. And it really isnt as on my debugger this.state.matches is an OBJECT.
What Im doing wrong here?
When you are fetching data with the once function it returns an object of that specific ref, in that case, it will return this ${auth.uid} data as an object.
So you might want to change your ref a little bit to: ref(/pools/${pool.key}/users/${auth.uid}/matches),
then to loop through the matches children, according to the firebase documentation https://firebase.google.com/docs/database/web/lists-of-data#listen_for_value_events
await firebaseApp.database()
.ref(`/pools/${pool.key}/users/${auth.uid}/matches`)
.once('value')
.then(snapshot =>{
snapshot.forEach(function(childSnapshot) {
var childKey = childSnapshot.key;
var childData = childSnapshot.val();
// ...
});
})

Categories