【问题标题】:how to get a ref key from a ref then search by the key and get data from that ref如何从参考中获取参考键然后按键搜索并从该参考中获取数据
【发布时间】:2020-02-29 12:57:31
【问题描述】:

我想读取帖子的数据并获取用户密钥,然后通过它进行搜索并同时获取用户数据,我尝试过,但它后退了一步,直到它不显示用户名我做任何其他动作

这里是帖子和经过身份验证的用户的 firebase 实时数据库

这是我尝试过的代码

userFullName = ''
    listenForCommunityAndPosts = () =>  {
        try {

            firebase.database().ref('posts').orderByChild('communityKey')
            .equalTo('-M07uNj9HbQxc_ich644'/*this.props.navigation.getParam("communityKey")*/)
            //.startAt('-M07uNj9HbQxc_ich644'/this.props.navigation.getParam("communityKey")/)
            .on('value', (dataSnapshot) =>{
                var postsList = [];
                dataSnapshot.forEach((child) => {
                    var userId = child.val().user
                    /**************/
                    firebase.database().ref('authenticatedUsers').child(userId).on('value', snap => {this.userFullName =  snap.val().fullName})
                    /**************/
                    postsList.push({
                        image: child.val().image,
                        text: child.val().text,
                        //user: child.val().user,
                        user: this.userFullName,
                        likesNumber: child.val().likesNumber,
                        commentsNumber: child.val().commentsNumber,
                        postKey: child.key
                    })
                })
                this.setState({ posts: postsList })
            })
        }
        catch(e){
            alert(e.message)
        }

    }

【问题讨论】:

    标签: javascript react-native firebase-realtime-database


    【解决方案1】:

    您现在在 posts 加载后调用 setState,这是在加载每个用户的用户名之前。因此,您的应用将显示没有用户名的用户。

    为确保它显示带有用户名的帖子,您需要在加载完所有用户名后调用setState。看起来像这样:

    firebase.database().ref('posts').orderByChild('communityKey')
    .equalTo('-M07uNj9HbQxc_ich644')
    .on('value', (dataSnapshot) =>{
        let promises = [];
        dataSnapshot.forEach((child) => {
            var userId = child.val().user
            let userRef = firebase.database().ref('authenticatedUsers').child(userId);
            promises.push(userRef.child('fullName').once('value'));
        })
    
        Promise.all(promises).then((snapshots) => {
            return snapshots.map((userNameSnapshot) => userNameSnapshot.val());
        }).then((userNames) => {
            let postsList = [];
            let index = 0;
            dataSnapshot.forEach((child) => {
                postsList.push({
                    image: child.val().image,
                    text: child.val().text,
                    user: userNames[index],
                    likesNumber: child.val().likesNumber,
                    commentsNumber: child.val().commentsNumber,
                    postKey: child.key
                })
                index = index + 1;
            });
    
            this.setState({ posts: postsList })
        });
    

    我改变了什么:

    • 用户现在加载了once() 侦听器,而不是on()。这可以确保您在例如用户名更改时不会添加帖子的另一个副本。请注意,您可以处理此类情况,但在这种情况下,您需要更新 postsList 中的现有条目,而不是添加新副本。
    • 监听器现在只加载用户名,因为这就是您所使用的全部内容。这将减少带宽使用量。
    • 它将所有加载操作放入promises 数组中,然后使用Promise.all“等待”所有操作完成。
    • 将所有用户名放入userNames 数组中,其顺序与dataSnapshot 中的顺序相同。
    • 基于dataSnapshot 和userNames 数组构建postsList。
    • 将结果列表放入状态,以便 React 呈现它。

    是否要多次调用setState 值得考虑。

    例如:帖子加载时一次,然后每个名称返回时一次。这样,您最初会看到没有用户名的帖子,然后看到每个用户名在加载时显示。

    或者,您只能在发布用户名后添加每个帖子。因此,在这种情况下,您不会在加载帖子后调用setState,而只能在加载每个帖子的用户名之后调用。

    这两个都是有效的替代方案,您可以使用上面代码的变体来实现。

    【讨论】:

      猜你喜欢
      • 2022-07-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-11
      • 1970-01-01
      • 2013-06-15
      • 2016-10-17
      相关资源
      最近更新 更多