javascript - 如何在 firebase 实时数据库上找到特定路径,然后使用文本输入更改该路径的值?
问题描述
流行测验,能手:
您正在构建一个反应原生应用程序。您将一些值设置为 firebase 作为应用程序根目录中的对象,如下所示:
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
}
您想为当前用户提供一个文本输入字段,如果他们是该公司的所有者,他们可以通过该字段更改该公司的舰队大小。
您的 Firebase 身份验证工作正常,因此您知道这firebase.auth().currentUser.email
将有助于检查以确定他们是否是所有者。
您的数据库值已设置 - 它们如下所示:
{
"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"
}
}
}
您将如何将初始信息呈现到屏幕上,以及如何设置文本输入逻辑以便用户输入更改数据库中的数据?
为了了解我的大脑,以及我是如何失败的,我在下面包含了我自己的代码作为起点。如果有办法向我展示如何采用我的基本策略并使其发挥作用——即使它并不优雅——我将不胜感激。但总的来说,我真的很纠结如何使用 Data Snapshot 获取数据路径引用并让它们可以在其他地方使用。
感谢您的帮助,任何人!
// 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>
);
}
}
解决方案
代码非常混乱,因此很难说出您要完成的工作。但让我在这里猜测一下:
- 你想从你的数据库中加载一个公司。
- 您知道公司所有者的电子邮件地址。
如果这是正确的,您可以使用查询来完成目标。就像是:
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
});
})
);
这里的变化:
- 使用查询仅选择具有正确 gmail 地址的公司。
- 循环遍历结果,因为(至少在 API 级别上)可能有多家公司对其
gmail
财产具有该价值。 - 摆脱整个迭代
Object.keys
和过滤,因为这使得它难以阅读。对于 Firebase 实时数据库代码,此结果也更惯用。 - 用于
self
跟踪this
实例,只是因为我不想计算bind
调用次数。
推荐阅读
- python - 如何为 pyttsx3 python 添加自己的 tts 声音
- android - kotlin.Unit 不能转换为 java.util.List。用于 getFilter 上的自定义适配器
- blockchain - 您如何为您的运行时编写系统测试?
- google-bigquery - 在 BigQuery 上使用以下查询时出现 TIMESTAMP 错误
- python - 为 anaconda 安装 cot-reports 模块
- html - Angular:以HTML显示上传文件的文件名
- c++ - 查找检测到的 blob opencv 的颜色
- r - 按位置加条件过滤器访问列
- python - 如何在 json 参数中传递多个“标题”值
- google-cloud-platform - Terraform Bigquery 创建表替换表而不是编辑