0

I currently work on the profile image page and I try to change the profile picture and store into Firebase Storage and Firebase Firestore. However, each time after I select the image and click save although the image details is saved into Firebase but it will display back the default image when I reload or navigate from other page back to the page? How can I display the image changes permanently each time I change the profile image, I have no idea how to do it, please teach me how to do it and place the code on where, appreaciate your help, thank you.

Profile Page Code:

// ignore_for_file: avoid_print, unused_local_variable, avoid_unnecessary_containers
import 'dart:io';
import 'dart:typed_data';
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:fyp_version1/light_dark_themes/theme.dart';
import 'package:fyp_version1/models/empty_content_animation_view.dart';
import 'package:fyp_version1/resources/image_utils.dart';
import 'package:fyp_version1/resources/upload_image_data.dart';
import 'package:fyp_version1/widgets/profile_text_box.dart';
import 'package:get/get.dart';
import 'package:image_picker/image_picker.dart';

class ProfilePage extends StatefulWidget {
  const ProfilePage({super.key});

  @override
  State<ProfilePage> createState() => _ProfilePageState();
}

class _ProfilePageState extends State<ProfilePage> {
  // current user
  final currentUser = FirebaseAuth.instance.currentUser!;
  late String imageUrl;

  // edit field
  Future<void> editField(String field) async {
    String newName = '';
    await showDialog(
      context: context,
      builder: (context) => AlertDialog(
        backgroundColor: Colors.grey[900],
        title: Text(
          'Edit $field',
          style: const TextStyle(
            color: Colors.white,
          ),
        ),
        content: TextField(
          autofocus: true,
          style: const TextStyle(color: Colors.white),
          decoration: InputDecoration(
            hintText: 'Enter new $field',
            hintStyle: const TextStyle(color: Colors.grey),
          ),
          onChanged: (value) {
            newName = value;
          },
        ),
        actions: [
          // cancel button
          TextButton(
            child: const Text(
              'Cancel',
              style: TextStyle(color: Colors.white),
            ),
            onPressed: () => Navigator.pop(context),
          ),
          // save button
          TextButton(
            child: const Text(
              'Save',
              style: TextStyle(color: Colors.white),
            ),
            onPressed: () => Navigator.of(context).pop(newName),
          ),
        ],
      ),
    );

    // update profile details in Firebase Firestore
    if (newName.trim().isNotEmpty) {
      // only update if there is something in the textfield
      await FirebaseFirestore.instance
          .collection('Users')
          .doc(currentUser.email)
          .update({field: newName});
    }
  }

  // change image
  Uint8List? _image;
//  File? image;

  void selectImage() async {
    Uint8List img = await pickImage(ImageSource.gallery);
    setState(() {
      _image = img;
    });
  }

  void saveProfile() async {
    String id;

    String resp = await StoreData().saveData(
      id: FirebaseAuth.instance.currentUser!.uid,
      name: currentUser.email as String,
      file: _image!,
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        centerTitle: true,
        title: const Text('Profile Page'),
        backgroundColor: primaryClr,
      ),
      body: Container(
        padding: const EdgeInsets.symmetric(horizontal: 32),
        child: StreamBuilder<DocumentSnapshot>(
          stream: FirebaseFirestore.instance
              .collection('Users')
              .doc(currentUser.email)
              .snapshots(),
          builder: (context, snapshot) {
            if (snapshot.hasData) {
              final userData = snapshot.data!.data() as Map<String, dynamic>;
              return Column(
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  Expanded(
                    child: ListView(
                      children: [
                        const SizedBox(height: 20),
                        Center(
                          child: Stack(
                            children: [
                              _image != null
                                  ? CircleAvatar(
                                      radius: 64,
                                      backgroundImage: MemoryImage(_image!),
                                    )
                                  : const CircleAvatar(
                                      radius: 64,
                                      backgroundImage: NetworkImage(
                                          'https://png.pngitem.com/pimgs/s/421-4212266_transparent-default-avatar-png-default-avatar-images-png.png'),
                                    ),
                              Positioned(
                                bottom: -10,
                                left: 80,
                                child: IconButton(
                                  onPressed: selectImage,
                                  icon: const Icon(Icons.add_a_photo),
                                ),
                              ),
                            ],
                          ),
                        ),
                        const SizedBox(height: 20),
                        Text(
                          currentUser.email!,
                          textAlign: TextAlign.center,
                          style: const TextStyle(color: Colors.black),
                        ),

                        const SizedBox(height: 50),
                        // user details
                        const Padding(
                          padding: EdgeInsets.only(left: 25.0),
                          child: Text(
                            'My Details',
                            style: TextStyle(color: Colors.black),
                          ),
                        ),

                        // username
                        ProfileTextBox(
                          text: userData['username'],
                          sectionName: 'username',
                          onPressed: () => editField('username'),
                        ),
                        const SizedBox(height: 50),
                        TextButton.icon(
                          onPressed: saveProfile,
                          icon: const Icon(Icons.save),
                          label: const Text('Save'),
                        )
                      ],
                    ),
                  ),
                ],
              );
            } else if (snapshot.hasError) {
              Get.snackbar(
                'Error',
                'Error${snapshot.error}',
                backgroundColor: Colors.white,
                snackPosition: SnackPosition.BOTTOM,
                colorText: Colors.black,
                icon: const Icon(
                  Icons.warning_amber_rounded,
                  color: Colors.red,
                ),
              );
            }
            return const EmptyContentsAnimationView();
          },
        ),
      ),
    );
  }
}

Upload Image to Storage and Firestore Code:

import 'dart:typed_data';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_storage/firebase_storage.dart';

final FirebaseStorage _storage = FirebaseStorage.instance;
final FirebaseFirestore _firestore = FirebaseFirestore.instance;

class StoreData {
  Future<String> uploadImageToStorage(String childName, Uint8List file) async {
    Reference ref = _storage.ref().child(childName);
    UploadTask uploadTask = ref.putData(file);
    TaskSnapshot snapshot = await uploadTask;
    String downloadUrl = await snapshot.ref.getDownloadURL();
    return downloadUrl;
  }

  Future<String> saveData({
    required String id,
    required String name,
    required Uint8List file,
  }) async {
    String resp = " Some Error Occurred";
    try {
      if (name.isNotEmpty) {
        String imageUrl = await uploadImageToStorage('profileImage', file);
        await _firestore.collection('userProfile').add({
          'id': FirebaseAuth.instance.currentUser!.uid,
          'name': name,
          'imageLink': imageUrl,
        });

        resp = 'success';
      }
    } catch (err) {
      resp = err.toString();
    }
    return resp;
  }
}

Image Utils Code:

// ignore_for_file: no_leading_underscores_for_local_identifiers, avoid_print

import 'package:image_picker/image_picker.dart';

pickImage(ImageSource source) async {
  final ImagePicker _imagePicker = ImagePicker();
  XFile? _file = await _imagePicker.pickImage(source: source);
  if (_file != null) {
    return await _file.readAsBytes();
  }
  print('No Images Selected');
}
I Can Done
  • 31
  • 4

0 Answers0