简体   繁体   English

如何在 flutter Firestore 数据更新期间显示成功消息并捕获错误

[英]How to show success message and catch error during flutter firestore data update

I have this function我有这个 function

Future updateMember(Member member) async {
  final User? user = Auth().currentUser;
  final docMember =
      FirebaseFirestore.instance.collection('users').doc(user?.uid);
  member.id = docMember.id;

  final json = member.toJson();
  final response = await docMember
      .update(json)
      .then((value) => {print("done")})
      .catchError((e) => (e));

  return response;
}

Then I want to catch the error here and success message here然后我想在这里捕获错误并在此处捕获成功消息

  final response = updateMember(member);
              if (response.then((value) => 'done') == true) {
                ScaffoldMessenger.of(context).showSnackBar(
                  const SnackBar(
                    content: Text('success'),
                    backgroundColor: Colors.green,
                  ),
                );
              } else {
                ScaffoldMessenger.of(context).showSnackBar(
                  const SnackBar(
                    content: Text(catchError(onError)),
                    backgroundColor: Colors.red,
                  ),
                );
              }

Please I need help on how I can implement this请我需要有关如何实现此功能的帮助

For this kind of purposes you could use a BLoC pattern, that divide an ui layer and domain layer (communication with server), you can read more on official documentation of bloc library: Bloc library It might be complicated to a novice in flutter, so, in your case, you can also implement state managment inside a single widget by your own.出于这种目的,您可以使用 BLoC 模式,它划分 ui 层和域层(与服务器通信),您可以阅读更多关于 bloc 库的官方文档: Bloc 库它可能对 flutter 中的新手来说很复杂,所以,在您的情况下,您还可以自己在单个小部件中实现 state 管理。

  1. Define stream and subscribe to it.定义 stream 并订阅它。
  late StreamController _controller;
  late StreamSubscription _subscriber;

  @override
  void initState() {
    _controller = StreamController<http.Response>();
    _subscriber = _controller.stream.listen((event) {
    });
    super.initState();
  }

In controller's stream we will add all server responses and work with those by _subscriber;在控制器的 stream 中,我们将添加所有服务器响应并使用 _subscriber 处理这些响应;

  1. Add to stream value to work with添加到 stream 值以使用
 final response = await docMember
      .update(json)
      .then((value) => {print("done")})
      .catchError((e) => (e));
      _controller.add(response);

Whenever you get response from server, you should call _controller.add(response), to add to our stream a new value.每当您收到来自服务器的响应时,您应该调用 _controller.add(response),向我们的 stream 添加一个新值。

  1. Handle responses in stream处理 stream 中的响应
  @override
  void initState() {
    _controller = StreamController<http.Response>();
    _subscriber = _controller.stream.listen((event) {
      if (event.statusCode < 200 || event.statusCode > 299)
      {
 ScaffoldMessenger.of(context).showSnackBar(
                  const SnackBar(
                    content: Text('error'),
                    backgroundColor: Colors.red,
                  ),
                );
       
      }
      else
      {
         ScaffoldMessenger.of(context).showSnackBar(
                  const SnackBar(
                    content: Text('success'),
                    backgroundColor: Colors.green,
                  ),
                );
      }
    });

    final response = await docMember
      .update(json)
      .then((value) => {print("done")})
      .catchError((e) => (e));
      _controller.add(response);
    super.initState();
  }

In stream you'l check if code is "OK", then show succes message, otherwise - error.在 stream 中,您将检查代码是否“OK”,然后显示成功消息,否则 - 错误。

All code snipped is showed below:截取的所有代码如下所示:

class ParentWidget extends StatefulWidget {
  ParentWidget({Key? key}) : super(key: key);

  @override
  State<ParentWidget> createState() => _ParentWidgetState();
}

class _ParentWidgetState extends State<ParentWidget> {
  late StreamController<http.Response> _controller;
  late StreamSubscription _subscriber;

  @override
  void initState() {
    _controller = StreamController<http.Response>();
    _subscriber = _controller.stream.listen((event) {
      if (event.statusCode < 200 || event.statusCode > 299)
      {
         ScaffoldMessenger.of(context).showSnackBar(
                  const SnackBar(
                    content: Text('success'),
                    backgroundColor: Colors.green,
                  ),
                );
      }
      else
      {
        ScaffoldMessenger.of(context).showSnackBar(
                  const SnackBar(
                    content: Text('error'),
                    backgroundColor: Colors.red,
                  ),
                );
      }
    });

    final response = await docMember
      .update(json)
      .then((value) => {print("done")})
      .catchError((e) => (e));
      _controller.add(response);
    super.initState();
  }

  @override
  void dispose() {
    _subscriber.cancel();
    _controller.close();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Text("Any widget")
    );
  }
}

This solves the problem这解决了问题

updateMember(member)
              .whenComplete(
                  () => ScaffoldMessenger.of(context).showSnackBar(
                        const SnackBar(
                          content: Text('succes'),
                          backgroundColor: Colors.green,
                        ),
                      ))
              .onError((error, stackTrace) =>
                  ScaffoldMessenger.of(context).showSnackBar(
                     SnackBar(
                      content: Text(error.toString()),
                      backgroundColor: Colors.red,
                    ),
                  ));
        });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM