首页 > 解决方案 > 更改 Firebase Firestore 上的数据后更新 Flutter UI

问题描述

我有一个带有用户名、电子邮件和个人资料图片的个人资料页面的应用程序。

我想要做的是,用户单击一个按钮来更改个人资料图片,打开一个带有简单圆形头像小部件和一个按钮的新页面,该页面会将图像上传到 Firebase 存储和 Firebase Firestore,添加到 Firestore该特定当前用户 uid 的集合。

一切正常,我可以看到 Firebase 存储上的更改,由 uid + 当前用户集合上的 URL 添加的图像。

这是edit_user_image_screen的代码:

import 'dart:io';

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:tradie_app/scr/providers/authService.dart';
import 'package:tradie_app/scr/widgets/loading.dart';

class EditCompanyImageScreen extends StatefulWidget {
  @override
  _EditCompanyImageScreenState createState() => _EditCompanyImageScreenState();
}

class _EditCompanyImageScreenState extends State<EditCompanyImageScreen> {
  // Keep track of the form for validation
  final _formKey = GlobalKey<FormState>();

  // Loading Icon
  bool loading = false;

  final AuthService _authService = AuthService();
  final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;
  final FirebaseFirestore _firebaseFirestore = FirebaseFirestore.instance;

  File _image;

  Future getImage(bool gallery) async {
    ImagePicker picker = ImagePicker();
    PickedFile pickedFile;
    // Let user select photo from gallery
    if (gallery) {
      pickedFile = await picker.getImage(
        source: ImageSource.gallery,
      );
    }
    setState(() {
      if (pickedFile != null) {
        _image = File(pickedFile.path);
        uploadFile(_image); // Use if you only need a single picture
      } else {
        print('No image selected.');
      }
    });
  }

  Future<String> uploadFile(File image) async {
    String downloadURL;
    Reference ref = FirebaseStorage.instance
        .ref()
        .child("images/${_firebaseAuth.currentUser.uid}");
    await ref.putFile(image);
    downloadURL = await ref.getDownloadURL();
    return downloadURL;
  }

  Future uploadToFirebase() async {
    final CollectionReference users =
        _firebaseFirestore.collection("Companies");
    final String uid = _firebaseAuth.currentUser.uid;

    String url = await uploadFile(
        _image); // this will upload the file and store url in the variable 'url'
    await users.doc(uid).update({'url': url});
    final result = await users.doc(uid).get();
    return result.data()["url"];
  }

  @override
  Widget build(BuildContext context) {
    return loading
        ? Loading()
        : Scaffold(
            appBar: AppBar(
              title: Text("Update Profile Image"),
            ),
            body: Form(
              key: _formKey,
              child: Column(
                children: [
                  Container(
                    child: Stack(
                      children: <Widget>[
                        Align(
                          alignment: Alignment.center,
                          child: IconButton(
                            icon: Icon(Icons.camera_alt),
                            onPressed: () async {
                              getImage(true);
                            },
                          ),
                        ),
                        Container(
                          child: _image != null
                              ? Container(
                                  height: 200,
                                  width: 200,
                                  decoration: BoxDecoration(
                                    image: DecorationImage(
                                        image: FileImage(
                                          _image,
                                        ),
                                        fit: BoxFit.contain),
                                  ),
                                )
                              : Container(
                                  decoration: BoxDecoration(
                                    color: Colors.grey[200],
                                    borderRadius: BorderRadius.circular(50),
                                  ),
                                  width: 100,
                                  height: 100,
                                  child: Icon(
                                    Icons.camera_alt,
                                    color: Colors.grey[800],
                                  ),
                                ),
                        ),
                      ],
                    ),
                  ),
                  Row(
                    children: [
                      ElevatedButton(
                        style: ElevatedButton.styleFrom(
                          primary: Colors.black,
                        ),
                        child: Text(
                          "Submit",
                          style: TextStyle(color: Colors.white),
                        ),
                        onPressed: () async {
                          uploadToFirebase();
                          Navigator.pop(context);
                        },
                      ),
                    ],
                  ),
                ],
              ),
            ),
          );
  }
}

在 company_profile_screen 上,我有这段代码:

Stream getCompanyImageData() async* {
    final CollectionReference users =
        _firebaseFirestore.collection("Companies");
    final String uid = _firebaseAuth.currentUser.uid;
    final result = await users.doc(uid).get();
    yield result.data()["url"];
  }

我的问题:

当我从 edit_user_image_screen 回到 company_screen 时,App UI 没有更新,我可以在 Firebase 上看到更改,如果我重新加载 Android Studio,我可以在 UI 上看到更改,但不是自动的。

这是我在 company_screen 上显示图像的代码:

Column(
    children: [
                                  StreamBuilder(
                                    stream: getCompanyImageData(),
                                    builder: (BuildContext context,
                                        AsyncSnapshot snapshot) {
                                      if (snapshot.connectionState ==
                                          ConnectionState.waiting) {
                                        return Center(
                                          child: CircularProgressIndicator(),
                                        );
                                      }
                                      return Image.network(
                                        snapshot.data.toString(),
                                        width: 100,
                                        height: 100,
                                      );
                                    },
                                  ),
                                ],
                              ),

标签: firebaseflutteruser-interfacegoogle-cloud-firestore

解决方案


这将取决于您的状态管理,

CollectionRef.users.doc(ViewModelUser.user.value.mobile).snapshots().listen((event) {
      ViewModelUser.setUser(UserModel.fromJson(event.data()));
    });

这是我的代码,我在其中监听我的个人资料中的更改,当有更改时,firebase 向我发送更新的数据并且我更新了我的 userData,我的状态管理完成了更新 UI 的其余部分。


推荐阅读