如何访问 Firebase 实时数据库中子节点的父节点?
Posted
技术标签:
【中文标题】如何访问 Firebase 实时数据库中子节点的父节点?【英文标题】:How to access parent of child node in Firebase Realtime Database? 【发布时间】:2019-10-11 13:33:08 【问题描述】:My Firebase Database Image 在 Firebase 的实时数据库中,我正在尝试访问被赋予子节点名称的父节点的名称。但是, .parent 似乎需要对子节点的引用,如果没有父节点的名称,我似乎无法获得。
这是我的数据的代码:
<script src="https://www.gstatic.com/firebasejs/5.7.3/firebase.js"></script>
<script src="https://apis.google.com/js/platform.js" async defer></script>
<style>
tr:hover background-color: #f5f5f5;
th, td
border-bottom: 1px solid #ddd;
</style>
<script>
// Initialize Firebase
var 配置 = apiKey: "AIzaSyA85okZdA9v_XAa9BgJJ2EOdUEbL09k0uY", authDomain: "fir-test-bcb6d.firebaseapp.com", 数据库URL: "https://fir-test-bcb6d.firebaseio.com", projectId: "fir-test-bcb6d", storageBucket: "fir-test-bcb6d.appspot.com", 消息发送者ID:“976121809263” ; firebase.initializeApp(config);
// Check to see if you are logged in
firebase.auth().onAuthStateChanged(function(user)
if (user == null)
alert("Not logged in.");
return;
else
userId = user.uid;
name = user.displayName;
imageUrl = user.photoURL;
email = user.email;
var user = firebase.auth().currentUser;
var newuser = user.getAdditionalUserInfo
user.sendEmailVerification().then(function()
// Email sent.
).catch(function(error)
// An error happened.
);
if (firebase.auth().currentUser.emailVerified)
alert('Email Verified');
console.log('Email Verified');
// write user data to users
//writeUserData(userId, name, email, imageUrl);
// moved to tweet function
// write data to document
mydiv = document.getElementById("mydata");
mydiv.innerhtml = name
myphotodiv = document.getElementById("myphoto");
myphotodiv.innerHTML = "<img src='" + imageUrl + "'/>";
firebase.database().ref('/tweets').once('value').then(function(snapshot)
var data = (snapshot.val());
if (data == null)
console.log("No data found at /tweets/" + userId);
else
firebase.database().ref('/users').once('value').then(function(snapshot)
var userdata = (snapshot.val());
if (userdata != null)
dataarray = [data,userdata]
console.log(dataarray)
updatetweets(dataarray);
);
//console.log(data)
//updatetweets(data);
);
// end user null check
); // end check auth state
function encodeImageFileAsURL()
var filesSelected = document.getElementById("inputFileToLoad").files;
if (filesSelected.length > 0)
var fileToLoad = filesSelected[0];
var fileReader = new FileReader();
fileReader.onload = function(fileLoadedEvent)
var srcData = fileLoadedEvent.target.result; // <--- data: base64
//var newImage = document.createElement('img');
//newImage.src = srcData;
//document.getElementById("imgTest").innerHTML = newImage.outerHTML;
document.getElementById("imgTest").innerHTML = srcData;
//console.log("Converted Base64 version is: " + document.getElementById("imgTest").innerHTML);
//console.log(srcData);
fileReader.readAsDataURL(fileToLoad);
// end function
// write user data
function writeUserData(userId, name, email, imageUrl)
firebase.database().ref('users/' + userId).once('value', function(snapshot)
if (!snapshot.exists())
firebase.database().ref('users/' + userId).set(
username: name,
email: email,
profile_picture : imageUrl
);
);
function updatetweets(data)
var tweetnumber = 0;
//var mylist = "<ul>";
var mytab = "<table id='tweettable'>";
users = data[1]; // put on top, because changed data - not good coding change later
data = data[0];
for (var u in data)
for (var t in data[u])
mytab = mytab + "<tr>";
var date = new Date(data[u][t].time);
var time = date.toString();
if (data[u][t].img != "")
mytab = mytab + "<td><img src='" + users[u].profile_picture + "' width='50px'></td>";
mytab = mytab + "<td>" + users[u].email + "</td>";
mytab = mytab + "<td>" + data[u][t].tweet + "</td>";
mytab = mytab + "<td>" + time + "<br><img src='" + data[u][t].img + "' width='300px'></td>";
mytab = mytab + "<td><p>Like this tweet</p>" + "<button id=" + t + " onclick=" + "like(this.id)" + ">Like</button>" + "<p>Likes: </p>" + "<p id='" + t + "likes'" + "'>" + data[u][t].likes + "</p>" + "</td>";
else
mytab = mytab + "<td><img src='" + users[u].profile_picture + "' width='50px'></td>";
mytab = mytab + "<td>" + users[u].email + "</td>";
mytab = mytab + "<td>" + data[u][t].tweet + "</td>";
mytab = mytab + "<td>" + time + "</td>";
mytab = mytab + "<td><p>Like this tweet</p>" + "<button id=" + t + " onclick=" + "like(this.id)" + ">Like</button>" + "<p>Likes: </p>" + "<p id='" + t + "likes'" + "'>" + data[u][t].likes + "</p>" + "</td>";
mytab = mytab + "</tr>";
//mylist = mylist + "</ul>";
mytab = mytab + "</table>"
var mytdiv = document.getElementById("mytweets");
//mytdiv.innerHTML = mylist;
mytdiv.innerHTML = mytab;
// write tweets to firebase
function tweet()
var twitdoc = document.getElementById("twit");
var twitimg = document.getElementById("imgTest");
var nameValue = twitdoc.value;
var imgValue = twitimg.innerHTML;
var d = new Date();
var dayofweek = d.getDay();
console.log(dayofweek);
var weekdays = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
var dayofmonth = d.getDate();
var monthnumber = d.getMonth();
var monthnames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
var year = d.getFullYear();
var thedate = weekdays[dayofweek] + ", " + monthnames[monthnumber] + " " + dayofmonth + ", " + year;
console.log(thedate);
var hours = d.getHours();
var minutes = d.getMinutes();
if (hours < 12)
var time =
var js_time = Date.now();
//var numberoffollowers = 2;
var tweetid = firebase.database().ref('tweets/' + userId + "/").push(tweet: nameValue, time: js_time, date: thedate, img: imgValue, likes: 0);
//var followers = firebase.database().ref('users/' + userId + "/").push(followers: numberoffollowers);
twitdoc.value = "";
writeUserData(userId, name, email, imageUrl);
console.log("tweet written")
firebase.database().ref('/tweets').once('value').then(function(snapshot)
var data = (snapshot.val());
if (data == null)
console.log("No data found at /tweets/" + userId);
else
firebase.database().ref('/users').once('value').then(function(snapshot)
var userdata = (snapshot.val());
if (userdata != null)
dataarray = [data,userdata]
console.log(dataarray)
updatetweets(dataarray);
);
);
// The unique key stored in tweetid is based on a timestamp, so list items will automatically be ordered chronologically. Because Firebase generates a unique key for each tweet, no write conflicts will occur if multiple users add a post at the same time. https://firebase.google.com/docs/database/admin/save-data
function like(t)
alert(t);
console.log('tvalue' + t);
console.log(t.ref());
var y = firebase.database().ref('/tweets/' + userId + "/" + t);
var parent = y.parent;
console.log('Parent: ' + parent);
var res = String(parent);
console.log(res);
var goal = res.substring((res.length - 28), res.length);
console.log(goal);
var oldlikes = document.getElementById(t + "likes").innerHTML;
console.log(oldlikes);
firebase.database().ref('/tweets/' + goal + "/" + t).once('value', function(snapshot)
console.log("/tweets/" + goal + "/" + t);
console.log(snapshot.val());
var oldlikenumber = snapshot.val().likes;
console.log(oldlikenumber);
var newlikes = oldlikenumber + 1;
var tweetid = firebase.database().ref('tweets/' + goal + "/" + t).update(likes: newlikes);
console.log(newlikes);
document.getElementById(t + "likes").innerHTML = newlikes;
);
/* console.log('liked tweetnumber' + tweetnumber);
alert('liked tweetnumber' + tweetnumber);
document.getElementById('tweetnumber' + tweetnumber).innerHTML = "Likes: " + 1;*/
//function follow
//
function signin()
console.log("Signing in");
var provider = new firebase.auth.GoogleAuthProvider();
firebase.auth().signInWithRedirect(provider).then(function(result)
window.location.replace("fbtest.html");
);
function signout()
console.log("Signing out");
firebase.auth().signOut().then(function()
);
</script>
<body>
<button onclick="signin()">Sign in</button>
<button onclick="signout()">Sign out</button>
<br>
<p>Step 1: delete your existing Firebase Realtime database</p>
<a href="fbtest.json" target="_target">Step 2: replace JSON Firebase rules for database</a><br>
<form>
Tweet:<br>
<textarea id="twit" type="text" name="thetweet" cols="100" rows="4"></textarea>
</form>
<button type="button" onclick="tweet()">Submit</button>
<br><input id="inputFileToLoad" type="file" onchange="encodeImageFileAsURL();" />
<div id="imgTest" style="display:none;"></div>
<div id="mytweets"></div>
<div id="mydata"></div>
<div id="myphoto"></div>
</body>
问题出在 like 函数中:带有 var y 的第一部分,如果我能找到一种方法来获取参数 t 表示的推文的发推人的用户 ID,那么所有这一切都是不必要的。
如果我能得到那个人的用户 ID(var whatever = 我需要的用户 ID),那么我可以写:
firebase.database().ref('/tweets/' + 不管什么 + "/" + t).once('value', function(snapshot)
//同样的东西
var tweetid = firebase.database().ref('tweets/' + 不管 + "/" + t).update(likes: newlikes);
【问题讨论】:
为什么在你已经知道父母的情况下要建立对孩子的引用?这是多余的。 首先,如果我不明白您在说什么,我深表歉意,因为我是 Firebase 和后端开发的初学者。让我解释一下——我正在建立一个社交媒体网站,每个帖子都有点赞功能。问题是我不知道父母,因为 userId 只是我的 userId (当前用户的)。我想获取发布推文的人的用户 ID,只知道孩子的名字(在图像的情况下是 -Lf_Klhw536655 ...)。 userId 是 tweetid 的父代,也就是上面的数字 (-Lf_Klhw536655 ...)。谢谢你 如果还不知道节点的完整路径,则无法构建对它的引用,如果这就是您所要求的。 好的,那你建议我如何解决这个问题? 您能否编辑问题以更具体地说明您要完成的工作?就目前而言,您并没有明确的问题陈述。 【参考方案1】:尽管这个问题已有一年之久,并且可能是 XY 问题,正如 cmets 所说,但我相信这可能会回答您的具体问题。当您不知道直接父级时,我知道以子级引用结束的唯一方法是您是否通过查询检索了孩子的孩子,在这种情况下,您可以使用 .ref 从 documentSnapshot 中获取父节点.key,像这样:
database().ref("/users/").orderByChild("name").startAt(someText).once('value')
.then(querySnapshot =>
querySnapshot.forEach(docSnapshot =>
console.log("parent = " + docSnapshot.ref.key);
// if this docSnapshot was retrieved because of child "name"'s value
// at https://someapp-firebaseio.com/users/uid8234/name
// then docSnapshot.ref.key == uid8234
)
)
例如,如果您将用户数据存储在 /users/ 中的 uid 节点下,并且“name”作为每个 uid 节点的子节点之一,则可能会发生这种情况。当然,为了避免检索到它,您还可以在“名称”旁边的另一个键中存储一个额外的 uid 副本并引用它。
【讨论】:
以上是关于如何访问 Firebase 实时数据库中子节点的父节点?的主要内容,如果未能解决你的问题,请参考以下文章
Firebase 实时规则如何检查具有 AutoID 的节点是不是包含正确的数据
如何使用 Java 将 Arraylist 数据写入 Firebase 数据库?
我在访问子节点时遇到问题。 (firebase 实时数据库 - 增量报告)