如何使用 React-Native 在 Firestore 中获取包含特定字符串的数组的文档

Posted

技术标签:

【中文标题】如何使用 React-Native 在 Firestore 中获取包含特定字符串的数组的文档【英文标题】:How to get documents with array containing a specific string in Firestore with React-Native 【发布时间】:2018-09-17 22:15:28 【问题描述】:

我刚刚开始使用 Firebase,正在尝试确定如何最好地构建我的 Firestore 数据库。

我想要的是从“events”集合中找到所有文档,其中“participants”(这是每个事件文档上的一个数组字段,其中包含带有键“displayName”和“uid”的对象)包含至少一个匹配的 uid .我要比较的 uid 列表将是用户的朋友。

因此,从语义上讲,我想使用事件参与者和用户朋友的 uid 来查找该事件的至少一个参与者是“朋友”的所有事件。

希望我没有失去你。也许这张截图会有所帮助。

这是我现在设计“事件”系列的方式

这样的深度查询可以通过 Firestore 实现吗?还是我需要在客户端进行过滤?

编辑 - 添加代码

      // TODO: filter events to only those containing friends

        // first get current users friend list
        firebase.firestore().doc(`users/$this.props.currentUser.uid`)
        .get()
        .then(doc => 
            return doc.data().friends
        ) 
        .then(friends =>  // 'friends' is array of uid's here
        // query events from firestore where participants contains first friend
        // note: I plan on changing this design so that it checks participants array for ALL friends rather than just first index. 
        // but this is just a test to get it working...
            firebase.firestore().collection("events").where("participants", "array-contains", friends[0])
            .get()
            .then(events => 
                // this is giving me ALL events rather than 
                // filtering by friend uid which is what I'd expect
                console.log(events)
                // update state with updateEvents()
                //this.props.dispatch(updateEvents(events))
            )
        )

我正在使用 React-Native-Firebase

"react-native": "^0.55.0",
"react-native-firebase": "^4.3.8",

【问题讨论】:

不要粘贴图片。粘贴您的代码 sn-p 添加代码 sn-p @yogkm 如果您可以将participants 作为一个集合添加到event 文档中,那么participants 集合中的每个文档的ID 都将是uid。然后您可以在event 文档内的participants 集合中查询匹配uid 的事件集合。您可以避免event 文档中的participants 数组。 感谢@Neelavar 的好建议,我做到了,现在可以查询子集合 【参考方案1】:

按照@Neelavar 所说的,然后更改我的代码以将 then() 链接到第一级集合查询中,能够解决这个问题。

            // first get current users' friend list
            firebase.firestore().doc(`users/$this.props.currentUser.uid`)
            .get()
            .then(doc => 
                return doc.data().friends
            )
            // then search the participants sub collection of the event
            .then(friends => 
                firebase.firestore().collection('events')
                .get()
                .then(eventsSnapshot => 
                    eventsSnapshot.forEach(doc => 
                        const  type, date, event_author, comment  = doc.data();
                        let event = 
                            doc, 
                            id: doc.id,
                            type,
                            event_author,
                            participants: [],
                            date,
                            comment,
                        
                        firebase.firestore().collection('events').doc(doc.id).collection('participants')
                        .get()
                        .then(participantsSnapshot => 
                            for(let i=0; i<participantsSnapshot.size;i++) 
                                if(participantsSnapshot.docs[i].exists) 
                                    // if participant uid is in friends array, add event to events array
                                    if(friends.includes(participantsSnapshot.docs[i].data().uid)) 
                                        // add participant to event
                                        let  displayName, uid  = participantsSnapshot.docs[i].data();
                                        let participant =  displayName, uid 
                                        event['participants'].push(participant)
                                        events.push(event)
                                        break;
                                    
                                
                            
                        )
                        .then(() => 
                            console.log(events)
                            this.props.dispatch(updateEvents(events))
                        )
                        .catch(e => console.error(e))
                    )
                )
                .catch(e => console.error(e))
            )

【讨论】:

以上是关于如何使用 React-Native 在 Firestore 中获取包含特定字符串的数组的文档的主要内容,如果未能解决你的问题,请参考以下文章

如何在 react-native 中使用 FormData?

如何使用 React-Native 在 iOS 中禁用屏幕截图

React-Native:如何在真实的 iOS 设备上使用“Remote JS Debugger”?

如何使用 redux 让根组件在 react-native 中重新渲染(开源项目)

React-Native + crypto:如何在 React-Native 中生成 HMAC?

如何在组件 React / React-native 的单独页面中使用动态 graphql(字符串)