Как получить документы с массивом, содержащим определенную строку в Firestore с React-Native - PullRequest
0 голосов
/ 18 сентября 2018

Я только начинаю с Firebase и пытаюсь определить, как лучше структурировать мою базу данных Firestore.

Я хочу найти все документы из коллекции «событий», где «участники» (поле массива в каждом документе события, содержащее объекты с ключами «displayName» и «uid») содержит как минимумодин соответствующий идентификатор.Список идентификаторов, с которыми я сравниваю, станет друзьями пользователей.

Поэтому в более семантических терминах я хочу найти все события, в которых хотя бы один из участников этого события является «другом», используяUID участников мероприятия и друзей пользователей.

Надеюсь, я не потерял вас.Может быть, этот скриншот поможет.

Вот как я спроектировал коллекцию 'событий' прямо сейчас enter image description here

Был бы такой глубокий запрос, как этот, с Firestore?Или мне нужно сделать фильтрацию на стороне клиента?

EDIT - добавлен код

      // 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",

1 Ответ

0 голосов
/ 18 сентября 2018

Это удалось выяснить, выполнив то, что сказал @Neelavar, а затем изменив мой код так, чтобы он затем связывался по цепочке затем () в запросе коллекции первого уровня.

            // 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)})
            })
...