firebase - Flutter,FieldValue.removeArray()无法正常工作

标签 firebase flutter dart google-cloud-firestore

我正在尝试从Firestore数据库中的列表中删除元素,但是它不起作用。我发现奇怪的是,FieldValue.arrayUnion()和FieldValue.delete()正常工作。为什么只有FieldValue.arrayRemove()不起作用?谢谢。

DB服务

 import 'package:cloud_firestore/cloud_firestore.dart';
    import 'package:firebase_auth/firebase_auth.dart';
    import "package:innovative_world/models/list_model.dart";

    class DatabaseService {
      // Collection Reference
      CollectionReference listCollection = Firestore.instance.collection("list");

      // Get current users id
      final String uid;
      DatabaseService({this.uid});

      // Set data to firestore db
      Future setUserData(List<String> list) async {
        return await listCollection.document(uid).setData({ 
          "list": list
        });
      }

      // DOES NOT WANT TO REMOVE ELEMENTS
      Future deleteListArr(int index) async {
        return await listCollection.document(uid)
          .updateData({ "list": FieldValue.arrayRemove([index]) });
      }

      // UserList snapshot
      UserList _userListFromSnapshot(DocumentSnapshot snapshot) {
        return UserList(
          uid: uid, 
          list: snapshot.data["list"].cast<String>().toList()
          ); 
      } 
      // Stream for user's to do list
      Stream<UserList> get userListStream {
        return listCollection.document(uid).snapshots()
          .map(_userListFromSnapshot);
      }
    }


  import "package:flutter/material.dart";
    import 'package:flutter/rendering.dart';
    import "package:innovative_world/services/auth_service.dart";
    import "package:innovative_world/models/list_model.dart";
    import 'package:innovative_world/services/database_service.dart';
    import "package:innovative_world/shared/decoration.dart";
    import 'package:innovative_world/shared/loading.dart';
    import 'package:provider/provider.dart';
    import "package:innovative_world/models/user_model.dart";
    import "package:innovative_world/models/list_model.dart";


    class Home extends StatefulWidget {
      @override
      _HomeState createState() => _HomeState();
    }

    class _HomeState extends State<Home> {
      String _text;
      final _formKey = GlobalKey<FormState>();
      List<String> userDoc = [];


      @override
      Widget build(BuildContext context) {
        final user = Provider.of<UserId>(context);

        return StreamBuilder<UserList>(
            stream: DatabaseService(uid: user.uid).userListStream,
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                UserList userList = snapshot.data;
                // List<String> userDoc = [userList.list.toString()];
                return Scaffold(
                  backgroundColor: Colors.blue[200],
                  appBar: AppBar(
                    title: Text(
                      "Create List",
                      style: TextStyle(
                        fontSize: 23.0,
                      ),
                    ),
                    elevation: 0.0,
                    actions: <Widget>[
                      FlatButton.icon(
                        onPressed: () {
                          AuthService().signOut();
                        },
                        icon: Icon(Icons.person),
                        label: Text("Sign out"),
                      ),
                    ],
                  ),
                  body: Padding(
                    padding: const EdgeInsets.fromLTRB(20.0, 25.0, 20.0, 0.0),
                    child: Column(
                      children: <Widget>[
                        Form(
                          key: _formKey,
                          child: Column(
                            children: <Widget>[
                              TextFormField(
                                validator: (val) =>
                                    val.isEmpty ? "Enter text" : null,
                                onChanged: (val) => setState(() => _text = val),
                                decoration: InputDecorationConst.copyWith(
                                    hintText: "Create List..."),
                              ),
                              RaisedButton(
                                onPressed: () async {
                                  if (_formKey.currentState.validate()) {
                                    userDoc.add(_text);

                                    _formKey.currentState.reset();
                                    await DatabaseService(uid: user.uid)
                                        .setUserData(userDoc ?? userList.list);
                                  }
                                },
                                color: Colors.pink,
                                child: Text(
                                  "Add to list",
                                  style: TextStyle(
                                      fontSize: 15.0, color: Colors.white),
                                ),
                              ),
                            ],
                          ),
                        ),
                        SizedBox(height: 15.0),
                        ListView.builder(
                          shrinkWrap: true,
                          itemCount: userList.list.length,
                          itemBuilder: (context, index) {
                            return ForList(index: index, theList: userList.list);
                          },
                        ),
                      ],
                    ),
                  ),
                );
              } else {
                return Loading();
              }
            });
      }
    }

    class ForList extends StatefulWidget {
      final int index;
      final List<String> theList;

      ForList({this.index, this.theList});

      @override
      _ForListState createState() => _ForListState();
    }

    class _ForListState extends State<ForList> {
      bool isSelected = false;

      @override
      Widget build(BuildContext context) {
        final user = Provider.of<UserId>(context);

        return Column(
          children: <Widget>[
            Card(
              child: CheckboxListTile(
                title: Text(widget.theList[widget.index]),
                value: isSelected,
                onChanged: (bool val)  {
                  setState(() {
                    isSelected = val;
                    if (isSelected) {
                    DatabaseService(uid: user.uid).deleteListArr(widget.index);
                    }
                  });
                },
              ),
            ),
          ],
        );
      }
    }

就在上面,我有一个单独的小部件“ForList”,其中保存了snapshot.data和索引,这对我来说似乎很好,但是我不知道为什么它不会从数据库中删除该元素

最佳答案

arrayRemove()无法工作的原因是,它不仅需要索引,还需要与其关联的字符串。
DB服务

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import "package:innovative_world/models/list_model.dart";

class DatabaseService {
  // Collection Reference
  CollectionReference listCollection = Firestore.instance.collection("list");

  // Get current users id
  final String uid;
  DatabaseService({this.uid});

  // Set data to firestore db
  Future setUserData(List<String> list) async {
    return await listCollection.document(uid).setData({ 
      "list": list
    });
  }

  // For deleting the lists
  Future deleteListArr(String index) async {
    return await listCollection.document(uid)
      .updateData({ "list": FieldValue.arrayRemove([index]) });
  }
  


  // UserList snapshot
  UserList _userListFromSnapshot(DocumentSnapshot snapshot) {
    return UserList(
      uid: uid, 
      list: snapshot.data["list"].cast<String>().toList()
      ); 
  } 
  // Stream for user's to do list
  Stream<UserList> get userListStream {
    return listCollection.document(uid).snapshots()
      .map(_userListFromSnapshot);
  }
}
import "package:flutter/material.dart";
import 'package:flutter/rendering.dart';
import "package:innovative_world/services/auth_service.dart";
import "package:innovative_world/models/list_model.dart";
import 'package:innovative_world/services/database_service.dart';
import "package:innovative_world/shared/decoration.dart";
import 'package:innovative_world/shared/loading.dart';
import 'package:provider/provider.dart';
import "package:innovative_world/models/user_model.dart";
import "package:innovative_world/models/list_model.dart";
import 'dart:async';

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  String _text;
  final _formKey = GlobalKey<FormState>();
  List<String> userDoc = [];
  // On every refresh the userDoc starts from 0, so it overrides the data

  @override
  Widget build(BuildContext context) {
    final user = Provider.of<UserId>(context);

    return StreamBuilder<UserList>(
        stream: DatabaseService(uid: user.uid).userListStream,
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            UserList userList = snapshot.data;
            // List<String> userDoc = [userList.list.toString()];
            return Scaffold(
              backgroundColor: Colors.blue[200],
              appBar: AppBar(
                title: Text(
                  "Create List",
                  style: TextStyle(
                    fontSize: 23.0,
                  ),
                ),
                elevation: 0.0,
                actions: <Widget>[
                  FlatButton.icon(
                    onPressed: () {
                      AuthService().signOut();
                    },
                    icon: Icon(Icons.person),
                    label: Text("Sign out"),
                  ),
                ],
              ),
              body: Padding(
                padding: const EdgeInsets.fromLTRB(20.0, 25.0, 20.0, 0.0),
                child: Column(
                  children: <Widget>[
                    Form(
                      key: _formKey,
                      child: Column(
                        children: <Widget>[
                          TextFormField(
                            validator: (val) =>
                                val.isEmpty ? "Enter text" : null,
                            onChanged: (val) => setState(() => _text = val),
                            decoration: InputDecorationConst.copyWith(
                                hintText: "Create List..."),
                          ),
                          RaisedButton(
                            onPressed: () async {
                              if (_formKey.currentState.validate()) {
                                userDoc.add(_text);
                                _formKey.currentState.reset();
                                await DatabaseService(uid: user.uid)
                                    .setUserData(userDoc ?? userList.list);
                              }
                            },
                            color: Colors.pink,
                            child: Text(
                              "Add to list",
                              style: TextStyle(
                                  fontSize: 15.0, color: Colors.white),
                            ),
                          ),
                        ],
                      ),
                    ),
                    SizedBox(height: 15.0),
                    ListView.builder(
                      shrinkWrap: true,
                      itemCount: userList.list.length,
                      itemBuilder: (context, index) {
                        return ForList(listsIndex: userList.list[index], index: index, theList: userList.list);
                      },
                    ),
                  ],
                ),
              ),
            );
          } else {
            return Loading();
          }
        });
  }
}

class ForList extends StatefulWidget {
  final int index;
  final String listsIndex;
  final List<String> theList;

  ForList({ this.listsIndex, this.index, this.theList });

  @override
  _ForListState createState() => _ForListState();
}

class _ForListState extends State<ForList> {
  bool isSelected = false;

  @override
  Widget build(BuildContext context) {
    final user = Provider.of<UserId>(context);

    return Column(
      children: <Widget>[
        Card(
          child: CheckboxListTile(
            title: Text(widget.theList[widget.index]),
            value: isSelected,
            onChanged: (bool val) {
              setState(() {
                isSelected = val;
                Timer(Duration(seconds: 1), () {
                  setState(() async {
                  if (isSelected) {
                    await DatabaseService(uid: user.uid).deleteListArr(widget.listsIndex);
                   
                    }
                  });
                });
              });
            },
          ),
        ),
      ],
    );
  }
}
现在,我在“ForList”实例“listsIndex”中添加了一个新参数,该参数包含索引旁边的字符串。

关于firebase - Flutter,FieldValue.removeArray()无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59906816/

相关文章:

javascript - 访问引号内的函数

flutter - Flutter/Dart-获取要在Text Widget中使用的PageView.Builder的索引号?

flutter 错误 : Execution failed for task ':app:compileFlutterBuildDebug

pdf - 任务 ':app:transformClassesWithMultidexlistForDebug'的执行失败。生成主dex列表时出错

android - Flutter firebase 无法直接登陆子页面

android - 根据距离在 Firebase 中搜索

Angular 火 2 错误 : The specified authentication provider is not enabled for this Firebase

javascript - 检索文档下的所有子集合

android - 当来自原生 android 方法 channel 的回调时,在 dart 中运行方法或函数

firebase - firebase_auth:禁用用户时,抛出PlatfromException而不是FirebaseAuthInvalidUserException?