I am making a call to my firestore like so:
firestore.collection('profiledata').doc(userID).get().then(doc => console.log(doc.data()))}
the data is being logged as it should be where I am saying console.log in the line above... It is returning data like so in my console:
{ "lastname": "xx", "firstname": "xxx", "companyname": "xxxx" }
what is the best way to output this data to my screen? I am quite new to react and am trying to learn! What I have so far is this:
render(){
return(
<div className='profile'>
<h1>User</h1>
{
<div>
<p>
First Name
Last Name
Company Name
</p>
</div>
)
})
}
</div>
Obviously this won't work, and those names last name, first name and company name are all just fillers, but how do I output this data to the screen? Any ideas?
Related
I have a Firebase database, the data looks like this:
Tickets
334
DateClosed: "",
DateOpened: "2022-01-10",
Description: "employee",
ID: "334",
Name: "linda",
Notes: "new hire"
I want to filter by 'DateClosed' and only display the tickets that have an empty string "" value for the 'DateClosed' property. Then I want to print these results to a basic <p> element or something, doesn't matter.
Using JS, HTML, CSS. This is the code I tried and failed:
const ref = db.ref('Tickets');
ref.orderByChild('DateClosed').equalTo("").on('child_added', (snapshot) => {
console.log(snapshot.key);
report.innerHTML=snapshot.val();
});
'report' refers to a <p> HTML element.
I might be getting the wrong end of the stick, but I am trying to pluralise a value with i18next package but also add in a static variable name:
Here is the json:
{
"likes": {
"pluralise_zero": "~~{{name}}~~ **liked** your post",
"pluralise_one": "~~{{name}}~~ and {{count}} other **liked** your post",
"pluralise_other": "~~{{name}}~~ and {{count}} others **liked** your post"
}
}
And I am calling it like so:
t('likes.pluralise', name, count)
The like count should be pluralised, but the {{name}} should not be. What I'm finding is that when I run this code, {{name}} is also pluralised like which looks something like:
{
count: 4
name0: "persons name"
name1: "another name"
name2: "someone else"
}
Is there a way to achieve what I need?
Pop quiz, hotshot:
You're building a react native app. You set some values to firebase as an object at the root of your app, like this:
firebase
.database()
.ref("/companies/")
.set({
awesomeCompany: {
name: "Awesome Company",
owner: "Joe Awesome",
gmail: "joeawesome#gmail.com",
fleetSize: 2
},
badCompany: {
name: "Bad Company",
owner: "Joe Bad",
gmail: "joebad#gmail.com",
fleetSize: 3
}
You want to give the current user a text input field through which they may change the fleetSize of a company if they are the owner of that company.
You have your firebase auth working properly, so you know that firebase.auth().currentUser.email will work to check against to determine if they are an owner.
Your database values have been set - they look like this:
{
"companies": {
"awesomeCompany": {
"fleetSize": 2,
"gmail": "joeawesome#gmail.com",
"name": "Awesome Company",
"owner": "Joe Awesome"
},
"badCompany": {
"fleetSize": 3,
"gmail": "joebad#gmail.com",
"name": "Bad Company",
"owner": "Joe Bad"
}
}
}
How would you render the initial information to the screen, and how would you set up the text input logic so that the user input changes data at the database?
To understand the brain I have, and how I'm failing, I'm including my own code below as a starting point. If there's a way to show me how I could take my basic strategy and make it work - even if it isn't elegant - I'd appreciate that. But overall I'm just really struggling with how to get data path references using Data Snapshot and keep them available to use elsewhere.
Thanks for your help, anyone!
// my crummy half baked code below
import React, { Component } from "react";
import { View, Text, TextInput, Button } from "react-native";
import { styles } from "../styles";
import * as firebase from "firebase";
export default class OwnerProfileScreen extends React.Component {
constructor(props) {
super(props);
this.state = {
gmail: null,
name: null,
fleetSize: null
};
}
componentDidMount() {
this.getData();
}
getData = () => {
const rootRef = firebase.database().ref(); // firebase reference
const authEmail = firebase.auth().currentUser.email; // current user
return rootRef.once("value").then(
function(snapshot) {
const idArray = Object.keys(snapshot.child("companies/").val()); // array of Ids
const companyData = idArray.map(id =>
snapshot.child("companies/" + id).val()
); // values of contained in objects at each key
const ownersCompany = companyData.filter(
obj => obj.gmail === authEmail
); // an array containing one object if the gmail address in the object is the same as the currentUser logged in
// what is the path of fleetSize?
// how do I define it to keep it available to use later
// with a Text Input event?
this.setState({
name: ownersCompany[0].name,
gmail: ownersCompany[0].gmail,
fleetSize: ownersCompany[0].fleetSize
});
}.bind(this)
);
};
changeFleetSize = userInput => {
//in order to set the user input to the database, I need the path
//of the fleetSize of the current user (who has been verified as an
// owner by comparing firebase auth to gmail addresses of company)
};
render() {
return (
<View style={styles.container}>
<Text>minPrice = {this.state.name}</Text>
<Text>gmail = {this.state.gmail}</Text>
<Text>fleetSize = {this.state.fleetSize}</Text>
<TextInput
style={{ height: 40, borderColor: "gray", borderWidth: 1 }}
//onChangeText currently does nothing since I don't know how
// to get the particular path of particular fleetSize
onChangeText={userInput => this.changeFleetSize(userInput)}
/>
</View>
);
}
}
The code is quite messy so it's hard to say what you're trying to accomplish. But let me make a guess here:
You want to load a single company from your database.
You know the email address of the owner of the company.
If that is correct, you can use a query to accomplish the goal. Something like:
var query = rootRef.child("companies").orderByChild("gmail").equalTo(authEmail);
var self = this;
query.once("value").then(function(result) {
result.forEach(function(snapshot) { // loop over result snapshots, since there may be multiple
const companyData = snapshot.val();
self.setState({
name: companyData.name,
gmail: companyData.gmail,
fleetSize: companyData.fleetSize
});
})
);
The changes here:
Use a query to only select the companies with the correct gmail address.
Loop over the results, since (on an API level at least) there could be multiple companies with that value for their gmail property.
Get rid of the whole iterating over Object.keys and filtering, since that made it hard to read. This result is also more idiomatic for Firebase Realtime Database code.
Use self to track the this instance, just because I didn't feel like counting bind calls.
I'm doing a small app where I display friend requests and an 'accept/reject' button beside each request.
here's my Template.notifications.helpers:
listRequests: function(){
return Notifications.find({toUser: Meteor.userId()});
}
and here's my notifications (where I display notifications for friend requests) template:
<template name="notifications">
{{#each listRequests}}
<p>{{displayUserName}}
<span id="fromUserId"><strong>{{fromUser}}</strong></span> sent you a friend request.
<button class="btn btn-primary" id="btnAcceptRequest">Accept</button>
<button class="btn btn-danger" id="btnRejectRequest">Reject</button>
</p>
<p>{{createdAt}}</p>
{{/each}}
</template>
And here's my user collection:
{
"_id": "zaSuTBgRh3oQcPSkh",
"emails": [
{
"address": "johnsmith#yahoo.com",
"verified": false
}
],
"profile": {
"firstname": "John",
"lastname": "Smith"
}
}
Currently, this code works. The issue is that it only displays the _id of the user who sent the request, thus, fromUser. What I wanted to do is display the firstname and lastname of the requesting user but I don't know where to go from here.
Of course, I tried replacing {{fromUser}} with {{profile.firstname profile.lastname}} and return Meteor.users.find({}); on the Template helpers but it does not work. Can anyone help me with this? Any help would be greatly appreciated.
You need a helper that does the lookup of the other user document and returns the appropriate values:
Template.notifications.helpers({
fromUserName: function(){
var fromUser = Meteor.users.findOne({ _id: this.fromUser });
if ( fromUser ){
return fromUser.profile.firstname + ' ' + fromUser.profile.lastname;
}
}
});
Note that if you have removed autopublish you must also be publishing the profile field (at least) from the user collection from the server and then subscribing to that on the client.
I've come across something so bizarre. I had this below set up to read from a data.json file. It should show up a list of people. Instead it's ignoring the json file and is reading out non existing words! I just want it to read from data.json. Even if I delete "data.json" , the search function still prints out these words which don't exist.
As you can see from the photo, it's showing up a list of words that I DO NOT have stored anywhere in my code or on my server. It's puzzling me.
<body ng-app="personApp">
<div class="container">
<header></header>
<div ng-controller="PersonListCtrl">
<div class="bar">Search:
<input ng-model="query">
</div>
<ul class="">
<li ng-repeat="person in persons | filter:query">{{person.name}}</li>
and
var personApp = angular.module('personApp', []);
personApp.controller('PersonListCtrl', function ($scope, $http) {
$http.get('js/data.json').success(function (data) {
$scope.persons = data;
})
});
data.json
[{
"name": "Mike Doe"
}, {
"name": "Jhon Doe"
}, {
"name": "Sam Doe"
}, {
"name": "Sam Doe"
}, ];
Go to browser console -> Network.
Most probably you will see 304 status of your request, that means ajax request was cached by browser. Either clean cache, add query string to request etc.