Flutter и Firebase: проблемы со структурой Basi c - PullRequest
0 голосов
/ 09 мая 2020

Возникли некоторые проблемы с пониманием того, как я должен использовать Firebase в логическом, структурном смысле.

У меня есть база данных, которая в настоящее время выглядит так:

enter image description here

В приложении, которое я использовал:

StreamBuilder(
  stream: Firestore.instance.collection('stores').snapshots(),
  builder: (context, snapshot) {
    <code here>
   }
 ),

Согласно всей документации и руководствам.

Но это возвращает циклы по всем моим документам , это все мои идентификаторы пользователей. Я не хочу этого, поскольку пользователь должен видеть только свои собственные данные. Но если я попытаюсь изменить его на:

stream: Firestore.instance.collection('stores').document(uid).snapshots(),

, то будет выдана ошибка, потому что вы можете циклически просматривать только коллекции документов, а не документы коллекций.

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

Collection:
  - application name
  Document: 
    - Stores
      Collection:
         - UID of user
           Fields:
             - Datafield1
             - Datafield2
             - Datafield3
             - Datafield4
             - etc etc etc

Чтобы попытаться заставить его соответствовать чему-то полезному. Но он не позволит вам сделать это и в Firebase, так как он будет использовать только поля в документах, а не в коллекциях.

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

stream: Firestore.instance.collection('stores').snapshots(),

Но я нигде в Интернете не могу найти об этом.

EDIT: @ SenpaiLeo

Раньше я возвращал свои данные так:

return ListView.builder(
  itemExtent: 500,
  itemCount: snapshot.data.documents.length,
  itemBuilder: (context, index) =>
      _buildListRows(context, snapshot.data.documents[index]),
);

А затем в _buildListRows:

Widget _buildListRows(BuildContext context, DocumentSnapshot document) {
...
  Container(
      child: TextField(
        controller: _storeNameController,
        decoration: InputDecoration(
           border: OutlineInputBorder(),
              hintText: document['store_name'],
           ),
        ),
    ),
    ...

Так что, возможно, теперь я изменил ссылку на основе вашей рекомендации, что теперь это:

document['store_name']

Неправильная ссылка?

Ответы [ 3 ]

1 голос
/ 09 мая 2020

Если вы используете это:

Collection:
  - Stores
     Document:
        - UID of user
         Collection:
            - Datafield1
            - Datafield2
            - Datafield3
            - Datafield4
            - etc etc etc

А затем выполните:

Firestore.instance.collection('stores').document(uid).snapshots()

Тогда приведенное выше должно получить только данные внутри документа uid, оно не получит под коллекции. Если вы хотите получить доступ к данным внутри подколлекции одного пользователя, используйте следующее:

Firestore.instance.collection('stores').document(uid).collection('userStore').snapshots()

Это получит все документы внутри подколлекции userStore


Решение :

child: StreamBuilder(
    stream: Firestore.instance.collection('stores').document(currentUserUID).snapshots(),
    builder: (BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
    if (snapshot.hasData) {
       return ListView.builder(
           shrinkWrap: true,
           itemCount: snapshot.data.data.length,
           itemBuilder: (context, index) =>
               _buildListRows(context, snapshot.data),
           );


Widget _buildListRows(BuildContext context, DocumentSnapshot document) {
return Container(
  height: MediaQuery.of(context).size.height * 0.8,
  child: ListView(
    children: <Widget>[
      Row(
        children: <Widget>[
          Padding(
            padding: EdgeInsets.fromLTRB(10, 0, 50, 0),
            child: Text(
              'Business Name',
              style: Theme
                  .of(context)
                  .textTheme
                  .body2,
            ),
          ),
          Container(
            height: 50,
            width: 200,
            padding: EdgeInsets.fromLTRB(5, 0, 5, 0),
            child: TextField(
              controller: _storeNameController,
              decoration: InputDecoration(
                border: OutlineInputBorder(),
                hintText: document['store_name'],
              ),
            ),
          ),
        ],
      ),

Этот Firestore.instance.collection('stores').document(currentUserUID).snapshots() получит документ текущего пользователя, затем для доступа к нему вы выполните snapshot.data.data["location"]

0 голосов
/ 11 мая 2020

(отправил решение от имени автора вопроса, чтобы переместить его в область ответов) .

Это работает для меня:

child: StreamBuilder(
    stream: Firestore.instance.collection('stores').document(currentUserUID).snapshots(),
    builder: (BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
    if (snapshot.hasData) {
       return ListView.builder(
           shrinkWrap: true,
           itemCount: snapshot.data.data.length,
           itemBuilder: (context, index) =>
               _buildListRows(context, snapshot.data),
           );


Widget _buildListRows(BuildContext context, DocumentSnapshot document) {
return Container(
  height: MediaQuery.of(context).size.height * 0.8,
  child: ListView(
    children: <Widget>[
      Row(
        children: <Widget>[
          Padding(
            padding: EdgeInsets.fromLTRB(10, 0, 50, 0),
            child: Text(
              'Business Name',
              style: Theme
                  .of(context)
                  .textTheme
                  .body2,
            ),
          ),
          Container(
            height: 50,
            width: 200,
            padding: EdgeInsets.fromLTRB(5, 0, 5, 0),
            child: TextField(
              controller: _storeNameController,
              decoration: InputDecoration(
                border: OutlineInputBorder(),
                hintText: document['store_name'],
              ),
            ),
          ),
        ],
      ),

Еще раз спасибо Питеру Хаддаду за его работу над этим!

0 голосов
/ 09 мая 2020
Stream<QuerySnapshot> stream = Firestore.instance.collection('stores').where('uid', isEqualTo: uid).snapshots();

Но я бы посоветовал прослушать изменения снимка и затем обновить нужную вам переменную.

...