Как зайти в firestore - PullRequest
       8

Как зайти в firestore

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

Я хочу создать представление для отображения некоторых событий внутри списка в моем приложении, например:

Event example

У меня есть две таблицы:

Пользователи enter image description here

События enter image description here

Но я не знаю, как сделать "внутреннее соединение" между таблицами USERS и EVENTS ...

Я пробовал это:

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:project/Methods.dart';
import 'package:project/Views/CadastroUsuario.dart';
import 'dart:math';

class EventClass{
  String owner;
  String description;
  String city;
  String state;
  String place;
}

class EventsListing extends StatefulWidget {
  @override
  EventsListingState createState() => new EventsListingState();
}

class EventsListingState extends State<EventsListing> {
  List<EventClass> events;

  @override
  void initState() {
    super.initState();
    events = new List<EventClass>();
  }

  void buildEventClass(DocumentSnapshot doc) async {
    EventClass oneEvent = new EventClass();

    DocumentReference document = Firestore.instance.collection("users").document(doc["userid"]);

    document.get().then((DocumentSnapshot snapshot){
      oneEvent.owner = snapshot["name"].toString();
    });
    oneEvent.description = doc["description"];
    oneEvent.place       = doc["place"];
    oneEvent.city        = doc["city"];
    oneEvent.state       = doc["state"];
    events.add(oneEvent);
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('Events'), 
      ),
      body: new StreamBuilder(
        stream: Firestore.instance.collection("events").snapshots(),
        builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot){
          if (snapshot.connectionState == ConnectionState.waiting)
            return Text("Loading...");

          return new ListView(
            padding: EdgeInsets.only(left: 5.0, right: 5.0, top: 5.0),
            children: snapshot.data.documents.map((document){
               buildEventClass(document);
               return events.length == 0 ? new Card() : item(events.last);
              }).toList()
          );
        },
      ),
      floatingActionButton: new FloatingActionButton(
        tooltip: 'New',
        child: new Icon(Icons.add),
        onPressed: () async {
          Navigation navigation = new Navigation();
          navigation.navigaTo(context, CadastroUsuario());
         },
      ),
    );
  }

  Widget item(EventClass oneEvent) {
    return new Card(
      elevation: 4.0,
      child: new Column(
        children: <Widget>[
          new Row(
            children: <Widget>[
              new Column(
                children: <Widget>[
                  new Text(oneEvent.owner.toString(),
                    style: TextStyle(fontSize: 20.0),
                    overflow: TextOverflow.ellipsis,),
                ],
              ),
              new Column(
                children: <Widget>[

                ],
              )
            ],
          ),
          new Container(
            color: Colors.blue,
            height: 150.0,
          ),
          new Row(
            children: <Widget>[
              new Row( 
                children: <Widget>[
                  new Text(oneEvent.description.toString(), 
                    style: TextStyle(fontSize: 20.0),
                    overflow: TextOverflow.ellipsis,),
                ],
              ),
              new Row( 
                children: <Widget>[
                  new Text(oneEvent.place.toString(), 
                    style: TextStyle(color: Colors.grey[350]),
                    overflow: TextOverflow.ellipsis,),
                ],
              ),
              new Row( 
                children: <Widget>[
                  new Text(oneEvent.city.toString() +' - '+ oneEvent.state.toString(), 
                    style: TextStyle(color: Colors.grey[350]),
                    overflow: TextOverflow.ellipsis,),
                ],
              )
            ]
          )          
        ],
      )
    );
  }
}

Но каждый раз, когда я пытаюсь показать эти события, я получаю это исключение

Exception has occurred.
PlatformException(error, Invalid document reference. Document references must have an even number of segments, but users has 1, null)

Что я делаю не так?Как я могу выполнить «внутреннее соединение» между этими таблицами и показать события?

Я использую Firebase Firestore.

PS: Я уже знаю, что Firestore - это база данных noSQL, и у меня естьнет «объединений», но я хочу сделать что-то вроде объединения.

1 Ответ

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

Как я говорил в комментариях, Firestore не поддерживает запросы на несколько коллекций, потому что это не реляционная БД.Если вам нужен доступ к нескольким коллекциям, вы будете управлять запросами независимо друг от друга.

Так я обычно получаю связанные данные коллекций (извините, это код JS, но я не знаю DART):

    var data = {};

    //First you get users data
    DocumentReference document = Firestore.collection("users")

    document.get().then((snapshot) => {

        //In this case I will store data in some object, so I can add events as an array for a key in each user object

        snapshot.forEach((userDoc) => {
            var userDocData = userDoc.data()

            if (data[userDoc.id] == undefined) {
                data[userDoc.id] = userDocData
            }

        })

        //So in this moment data object contains users, now fill users with events data

//In this var you count how many async events have been downloaded, with results or not.    
var countEvents = 0

        Object.keys(data).forEach((userDocId) => {

    //Here Im creating another query to get all events for each user

            SnapshotReference eventsForCurrentUserRef = Firestore.collection("events").where("userId", "==", userDocId)

            eventsForCurrentUserRef.get.then((eventsForUserSnapshot) => {
//Count events
countEvents++

                eventsForUserSnapshot.forEach((eventDoc) => {

                    var eventDocData = eventDoc.data()

                    //Check if array exists, if not create it
                    if (data[eventDocData.userId].events == undefined) {
                        data[eventDocData.userId].events = []
                    }

                    data[eventDocData.userId].events.push(eventDocData)


                })

if(countEvents == Object.keys(data).length){
//Lookup for events in every user has finished
}

            })


        })

    })
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...