Firebase 个人资料图片无法在 flutter 中检索

问题描述 投票:0回答:0

我面临的主要问题与使用 Firebase Storage 在 Flutter 应用程序中显示个人资料图像有关。

重新加载后图片不显示:上传图片后,重新加载或再次登录后,个人资料页面不显示上传的图片。该问题与从 Firebase 存储检索下载 URL 并将其与 Firestore 中的用户个人资料数据相关联有关。我也看不到上传到 firestore 的照片链接。

为了解决这些问题,代码已更新以正确检索和显示个人资料图像。下载 URL 是从 Firebase 存储中获取并存储在 Firestore 中,因此可以稍后访问以显示图像。

最终代码应允许用户上传其个人资料图像,在个人资料页面上查看它们,并通过 Firestore 中存储的下载 URL 从 Firebase 存储中获取上传的图像,从而跨会话保留上传的图像。

提前谢谢您!}

class ProfilePage extends StatefulWidget {
  @override
  _ProfilePageState createState() => _ProfilePageState();
}

class _ProfilePageState extends State<ProfilePage> {
  Uint8List? _imageData;


  void _selectImage() async {
    final pickedFile = await FilePicker.platform.pickFiles(type: FileType.image);
    if (pickedFile != null) {
      setState(() {
        _imageData = pickedFile.files.first.bytes;
      });
      await _uploadImageToFirebase();
    }
  }


  // Function to check if the file has an allowed extension (png, jpg, jpeg)
  bool _isAllowedImage(Uint8List data) {
    final mimeType = lookupMimeType('file.jpg', headerBytes: data);
    if (mimeType != null &&
        (mimeType.startsWith('image/jpeg') ||
            mimeType.startsWith('image/png'))) {
      return true;
    }
    return false;
  }

  // Display the image in the CircleAvatar if it's allowed
  Widget _buildProfileImage() {
    if (_imageData != null && _isAllowedImage(_imageData!)) {
      return CircleAvatar(
        radius: 50,
        backgroundImage: MemoryImage(_imageData!),
      );
    } else {
      // If the image is not available locally, load it from Firebase Storage
      return StreamBuilder<DocumentSnapshot>(
        stream: _firestore.collection('admin_users').doc(_uid).snapshots(),
        builder: (context, snapshot) {
          if (!snapshot.hasData || !snapshot.data!.exists) {
            return CircleAvatar(
              radius: 50,
              backgroundImage: AssetImage('assets/profile_picture_placeholder.png'),
            );
          }
          Map<String, dynamic>? userData = snapshot.data?.data() as Map<String, dynamic>?;

          String? downloadURL = userData?['profile_image_url'];

          if (downloadURL != null && downloadURL.isNotEmpty) {
            return CircleAvatar(
              radius: 50,
              backgroundImage: NetworkImage(downloadURL),
            );
          } else {
            return CircleAvatar(
              radius: 50,
              backgroundImage: AssetImage('assets/profile_picture_placeholder.png'),
            );
          }
        },
      );
    }
  }

  final FirebaseAuth _auth = FirebaseAuth.instance;
  final FirebaseFirestore _firestore = FirebaseFirestore.instance;
  final TextEditingController _firstNameController = TextEditingController();
  final TextEditingController _lastNameController = TextEditingController();
  final TextEditingController _regionController = TextEditingController();
  final TextEditingController _phoneNumberController = TextEditingController();

  String? _uid;
  bool _isLoading = false;

  @override
  void initState() {
    super.initState();
    _getCurrentUser();
  }

  Future<void> _getCurrentUser() async {
    final user = _auth.currentUser;
    if (user != null) {
      setState(() {
        _uid = user.uid;
      });
      await _getUserData();
    }
  }

  Future<void> _getUserData() async {
    if (_uid != null) {
      final userData = await _firestore.collection('admin_users').doc(_uid).get();
      if (userData.exists) {
        setState(() {
          _firstNameController.text = userData.get('first_name') ?? '';
          _lastNameController.text = userData.get('last_name') ?? '';
          _regionController.text = userData.get('region') ?? '';
          _phoneNumberController.text = userData.get('phone_number') ?? '';
        });
      }
    }
  }

  Future<void> _uploadImageToFirebase() async {
    if (_imageData != null) {
      try {
        String uid = _auth.currentUser?.uid ?? '';
        String fileName = 'profile_images/$uid.jpg';

        // Upload the image to Firebase Storage
        await firebase_storage.FirebaseStorage.instance.ref(fileName).putData(_imageData!);

        // Get the download URL of the uploaded image
        String downloadURL =
        await firebase_storage.FirebaseStorage.instance.ref(fileName).getDownloadURL();

        // Save the download URL in Firestore
        if (_uid != null) {
          final userData = {
            'profile_image_url': downloadURL,
            'first_name': _firstNameController.text.trim(),
            'last_name': _lastNameController.text.trim(),
            'region': _regionController.text.trim(),
            'phone_number': _phoneNumberController.text.trim(),
          };
          await _firestore.collection('admin_users').doc(_uid).update(userData);
        }
      } catch (e) {
        print('Error uploading image: $e');
      }
    }
  }


  Future<void> _updateUserData() async {
    if (_uid != null) {
      final userData = {
        'first_name': _firstNameController.text.trim(),
        'last_name': _lastNameController.text.trim(),
        'region': _regionController.text.trim(),
        'phone_number': _phoneNumberController.text.trim(),
      };

      await _firestore.collection('admin_users').doc(_uid).set(userData);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Profile Page'),
        leading: IconButton(
          icon: Icon(Icons.arrow_back),
          onPressed: () {
            Navigator.pushReplacement(
              context,
              MaterialPageRoute(builder: (context) => AdminPage()),
            );
          },
        ),
      ),
      body: _isLoading
          ? Center(
        child: CircularProgressIndicator(),
      )
          : SingleChildScrollView(
        padding: EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            Stack(
              alignment: Alignment.center,
              children: [
                _buildProfileImage(),
                Positioned(
                  child: IconButton(
                    onPressed: _selectImage,
                    icon: Icon(Icons.add_a_photo),
                    color: Colors.white,
                  ),
                ),
              ],
            ),
            SizedBox(height: 16),
            Row(
              children: [
                Expanded(
                  child: Padding(
                    padding: const EdgeInsets.all(16.0),
                    child: TextField(
                      controller: _firstNameController,
                      decoration: InputDecoration(labelText: 'First Name'),
                    ),
                  ),
                ),
                Expanded(
                  child: Padding(
                    padding: const EdgeInsets.all(16.0),
                    child: TextField(
                      controller: _lastNameController,
                      decoration: InputDecoration(labelText: 'Last Name'),
                    ),
                  ),
                ),
              ],
            ),
            SizedBox(height: 16),
            Padding(
              padding: const EdgeInsets.all(16.0),
              child: TextField(
                controller: _regionController,
                decoration: InputDecoration(labelText: 'Region'),
              ),
            ),
            SizedBox(height: 16),
            Padding(
              padding: const EdgeInsets.all(16.0),
              child: TextField(
                controller: _phoneNumberController,
                decoration: InputDecoration(labelText: 'Phone Number'),
              ),
            ),
            SizedBox(height: 16, width: 30),
            ElevatedButton(
              onPressed: () async {
                setState(() {
                  _isLoading = true;
                });
                await _updateUserData();
                setState(() {
                  _isLoading = false;
                });
                ScaffoldMessenger.of(context).showSnackBar(
                  SnackBar(content: Text('Profile updated successfully')),
                );
              },
              child: Text('Save'),
            ),
          ],
        ),
      ),
    );
  }
}
flutter google-cloud-firestore firebase-storage
© www.soinside.com 2019 - 2024. All rights reserved.