Fetching data from firebase database and my output to simulator is duplicated. I know why data is pushed 2 times to 'items'. How can i solve this issue and push items from every child to 'addData' only once?
My code:
constructor(props) {
super(props);
this.state = {
arrData:[]
};
}
componentDidMount = () => {
var self = this;
var items = [];
database.ref("eventAttenders/2188058178082419").orderByKey().once("value")
.then(function(snapshot) {
snapshot.forEach(function(childSnapshot) {
var key = childSnapshot.key;
const key = childSnapshot.key;
database.ref(`users/${key}`).once("value")
.then(function(snapshot) {
snapshot.forEach(function(childSnapshot) {
var data = snapshot.val();
items.push({
name: data.name,
phone: data.phone,
});
});
});
});
});
self.setState({arrData: items})
}
Database screenshot:
Simulator screenshot:
Because you are adding the push method in snapshot.forEach(function(childSnapshot) { this not required, try removing it.
componentDidMount = () => {
var self = this;
var items = [];
database.ref("eventAttenders/2188058178082419").orderByKey().once("value")
.then(function(snapshot) {
snapshot.forEach(function(childSnapshot) {
var key = childSnapshot.key;
const key = childSnapshot.key;
database.ref(`users/${key}`).once("value")
.then(function(snapshot) {
var data = snapshot.val();
items.push({
name: data.name,
phone: data.phone,
});
});
});
});
self.setState({arrData: items})
}
Related
I want to bring the user location with cloudflare. Localhost and google cloud bring different results. I want to access the location information of the member, not the server. What can I use instead of getStaticProps?
My Code;
export async function getStaticProps() {
const one = await fetch("https://www.cloudflare.com/cdn-cgi/trace");
const two = await one.text();
var data = two.replace(/[\r\n]+/g, '","').replace(/\=+/g, '":"');
data = '{"' + data.slice(0, data.lastIndexOf('","')) + '"}';
var locale = JSON.parse(data);
return {
props: { locale },
};
}
function myPage(props) {
return (props.locale.loc)
}
solved code;
let [locData, setLocData] = useState("EN");
useEffect(() => {
fetch("https://www.cloudflare.com/cdn-cgi/trace")
.then((response) => response.text())
.then((two) => {
var data = two.replace(/[\r\n]+/g, '","').replace(/\=+/g, '":"');
data = '{"' + data.slice(0, data.lastIndexOf('","')) + '"}';
var locale = JSON.parse(data);
setLocData(locale.loc);
});
}, []);
How to query collection of firebase so that it also includes its subcollection? So I have collection posts with documents and every document has field subcollection likes. After getting collection posts I have objects and inside them values of fields, but inside each object (post) I want to have besides those values an object aka subcollection likes.
Queries in Firestore are by definition shallow. There is no way to get results from both a parent collection and its subcollections in a single query.
When I want all data from a parent document and a subcollection in the same operation, and it's not too much, I typically (also) include it in the parent document.
Ive done in it this function but i dont feel like making it look pretty theres tons of code that isnt needed here anyways here is solution maybe it helps someone:
getPosts = async () => {
this.setState({ isLoading: true });
const snapshot = await firebase
.firestore()
.collectionGroup("posts")
.orderBy("id", "desc")
.limit(7)
.get();
let array = [];
const snap = await firebase
.firestore()
.collection("posts")
.get();
for (let i = 0; i < snap.docs.length; i++) {
array.push(snap.docs[i].data().id);
//console.log(array);
//newpost[i].userHandle = [result]; //your new object here
}
if (!snapshot.empty) {
let newpost = [];
this.setState({ lastDoc: snapshot.docs[snapshot.docs.length - 1] });
// snapshot.forEach((doc) => {
// const PostItem = doc.data();
// PostItem.id = doc.id;
// newpost.push(PostItem);
// });
let newpost2 = [];
let result = [];
let finish = [];
let groupByKey = [];
let bruh = [];
let uf = [];
const listOfPosts = await firebase.firestore().collection("posts").get()
.then((val) => val.docs);
for (var i=0; i<listOfPosts.length; i++)
{
const snapshot = await firebase.firestore().collection("posts").doc(
listOfPosts[i].id.toString())
.collection("hugs").get();
snapshot.forEach(doc => {
newpost2.push(doc.data());
result = newpost2.map(a => a.userHandle)
//console.log(newpost2)
newpost2.map(obj=> ({ ...obj, result}))
//console.log(newpost2)
groupByKey.push((list, key, {omitKey=false}) => list.reduce((hash, {[key]:value, ...rest}) => ({...hash, [value]:( hash[value] || [] ).concat(omitKey ? {...rest} : {[key]:value, ...rest})} ), {}))
groupByKey.push((newpost2, 'id', {omitKey:false}))
uf = [];
newpost2.forEach((obj)=> {
if(typeof uf[obj.id] === 'undefined') {
uf[obj.id] = {id: obj.id, userHandle: [obj.userHandle]}
}
else {
uf[obj.id].userHandle.push(obj.userHandle);
}
});
uf = uf.filter(item => !(item == "undefined"));
//console.log(groupByKey)
//this.setState({ post: [...newpost,] });
});
//finish = a1.map(t1 => ({...t1, ...a2.find(t2 => t2.id === t1.id)}))
//console.log(newpost2)
}
for (let i = 0; i < snapshot.docs.length; i++) {
newpost.push(snapshot.docs[i].data());
//newpost[i].username = result;
//newpost[i].userHandle = [result]; //your new object here
}
//var element = {}, cart = [];
//newpost.id = id;
//element.quantity = quantity;
//newpost2.push(newpost);
// Array of Objects in form {element: {id: 10, quantity: 10} }
finish = newpost.map(t1 => ({...t1, ...uf.find(t2 => t2.id === t1.id)}))
//if(Object.keys(groupByKey) === t1.id){console.log("nigba")}
//var result2 = newpost.map(function(e) {
//var find = groupByKey.find(a => a.email == e.email);
//return console.log(Object.assign({}, e, find))
//})
console.log(finish)
this.setState({ post: [...newpost,] });
//console.log(this.state.post)
} else {
this.setState({ lastDoc: null });
}
this.setState({ isLoading: false });
//setTimeout(
//console.log(this.state.post)
//, 50000);
};
I am working on a Blazor application which needs the screen to be shared. I found how to read and display the screen in the Razor page, once it receives the signaled message from the client, which is an Electron application. This is the code for the Electron Application.
const { desktopCapturer } = require('electron')
const signalR = require('#microsoft/signalr')
let connection;
let subject;
let screenCastTimer;
let isStreaming = false;
const framepersecond = 10;
const screenWidth = 1280;
const screenHeight = 800;
async function initializeSignalR() {
connection = new signalR.HubConnectionBuilder()
.withUrl("http://localhost:51064")
.configureLogging(signalR.LogLevel.Information)
.build();
connection.on("NewViewer", function () {
if (isStreaming === false)
startStreamCast()
});
connection.on("NoViewer", function () {
if (isStreaming === true)
stopStreamCast()
});
await connection.start().then(function () {
console.log("connected");
});
return connection;
}
initializeSignalR();
function CaptureScreen() {
return new Promise(function (resolve, reject) {
desktopCapturer.getSources({ type: ['screen'], thumbnailSize: { width: screenWidth, height: screenHeight } },
(error, sources) => {
if (error) console.error(error);
for (const source of sources) {
if (source.name === 'Entire screen') {
resolve(source.thumbnail.toDataURL())
}
}
})
})
}
const agentName = document.getElementById('agentName');
const startCastBtn = document.getElementById('startCast');
const stopCastBtn = document.getElementById('stopCast');
stopCastBtn.setAttribute("disabled", "disabled");
startCastBtn.onclick = function () {
startCastBtn.setAttribute("disabled", "disabled");
stopCastBtn.removeAttribute("disabled");
connection.send("AddScreenCastAgent", agentName.value);
};
function startStreamCast() {
isStreaming = true;
subject = new signalR.Subject();
connection.send("StreamCastData", subject, agentName.value);
screenCastTimer = setInterval(function () {
try {
CaptureScreen().then(function (data) {
subject.next(data);
});
} catch (e) {
console.log(e);
}
}, Math.round(1000 / framepersecond));
}
But I am trying to figure out the equivalent of these lines of code:
const { desktopCapturer } = require('electron')
const signalR = require('#microsoft/signalr')
desktopCapturer.getSources({ type: ['screen'], thumbnailSize: { width: screenWidth, height: screenHeight } },
in an HTML page when signalR.js is used.
Help would be very much appreciated !
I'm trying to crawl a webpage that has a h3 tag under an a tag. I'm getting the a tag just fine, but when trying to get the innerText of h3 I'm getting an undefined value.
This is what I'm trying to crawl:
const puppeteer = require('puppeteer');
const pageURL = "https://producthunt.com";
const webScraping = async pageURL => {
const browser = await puppeteer.launch({
headless: false,
arges: ["--no-sandbox"]
});
const page = await browser.newPage();
let dataObj = {};
try {
await page.goto(pageURL, { waitUntil: 'networkidle2' });
const publishedNews = await page.evaluate(() => {
const newsDOM = document.querySelectorAll("main ul li");
let newsList = [];
newsDOM.forEach(linkElement => {
const text = linkElement.querySelector("a").textContent;
const innerText = linkElement.querySelector("a").innerText;
const url = linkElement.querySelector("a").getAttribute('href');
const title = linkElement.querySelector("h3").innerText;
console.log(title);
newsList.push({
title,
text,
url
});
});
return newsList;
});
dataObj = {
amount: publishedNews.length,
publishedNews
};
} catch (e) {
console.log(e);
}
console.log(dataObj);
browser.close();
return dataObj;
};
webScraping(pageURL).catch(console.error);
Console log works great, but puppeteer throws:
Cannot read property 'innerText' of null
It looks like your solution is working just fine, but you're not controlling whether the h3 tag is null or not. Try adding an if statement before accessing the innerText attribute, or use the code I left below.
const puppeteer = require('puppeteer');
const pageURL = "https://producthunt.com";
const webScraping = async pageURL => {
const browser = await puppeteer.launch({
headless: false,
arges: ["--no-sandbox"]
});
const page = await browser.newPage();
let dataObj = {};
try {
await page.goto(pageURL, { waitUntil: 'networkidle2' });
const publishedNews = await page.evaluate(() => {
let newsList = [];
const newsDOM = document.querySelectorAll("main ul li");
newsDOM.forEach(linkElement => {
const aTag = linkElement.querySelector("a");
const text = aTag.textContent;
const innerText = aTag.innerText;
const url = aTag.getAttribute('href');
let title = aTag.querySelector("h3");
// there may be some <a> without an h3, control
// the null pointer exception here, accessing only
// if title is not 'null'.
if (title) title = title.innerText;
console.log(title);
// changed the object structure to add a key for each attr
newsList.push({
title: title,
text: text,
url: url
});
});
return newsList;
});
// changed the object structure to add a key for the array
dataObj = {
amount: publishedNews.length,
list: publishedNews
};
} catch (e) {
console.log(e);
}
console.log({receivedData: dataObj});
browser.close();
return dataObj;
};
webScraping(pageURL).catch(console.error);
Let me know if this fixes your problem!
My database looks like that:
I know how to fetch genUserID and genUserID2 and renrder info to Flatlist. But how can i make two request to one fatlist?
I would like to get ids from eventAttenders/2188058178082419 and then get names from users database. User id comes from previous request.
My code:
constructor(props) {
super(props);
this.state = {
arrData:[]
};
}
componentDidMount = () => {
var ref = firebase.database().ref("eventAttenders/2188058178082419");
ref.once('value').then(snapshot => {
var items = [];
snapshot.forEach((child) => {
items.push({
id: child.val().id,
name: child.val().name,
email: child.val().yks,
});
});
this.setState({ arrData: items});
});
}
Umm, if understood your question correctly, the easy fix would be get all the ids first then with loop, get one more ref to the userlist and get the data.
constructor(props) {
super(props);
this.state = {
arrData:[]
};
}
componentDidMount = () => {
var ref = firebase.database().ref("eventAttenders/2188058178082419");
var items = [];
ref.once('value').then(snapshot => {
snapshot.forEach((child) => {
const { id } = child;
console.log(id) //make sure you are getting two ids genUserID and
// genUserID2 from 2188058178082419 ref
firebase.database().ref(`users/${id}`).once('value').then(childsnapshot => {
childsnapshot.forEach(keys => {
console.log(keys);
items.push({
name: keys.name,
phone: keys.phone,
});
});
});
this.setState({ arrData: items});
});
}