1. Anuncie Aqui ! Entre em contato fdantas@4each.com.br

[Flutter] Cover photo is not displaying from another ui

Discussão em 'Mobile' iniciado por Stack, Outubro 17, 2024 às 17:03.

  1. Stack

    Stack Membro Participativo

    So I have a flutter app where on one page I add the cover photo of the program user tries to create and I want to display that cover photo on his profile, I will leave here video to understand the issue better: https://imgur.com/a/u2Lz6IJ . Here it's the page where user upload cover photo by using button 'Edit' and add it to storage :

    class _WorkoutContentAddedState extends State<WorkoutContentAdded> {
    String? coverPhotoUrl;
    File? _image;

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

    Future<void> _loadCoverPhotoUrl() async {
    try {
    final docRef = FirebaseFirestore.instance.collection('programs').doc('your_program_id');
    final docSnapshot = await docRef.get();

    if (docSnapshot.exists) {
    final data = docSnapshot.data();
    if (data != null && data.containsKey('coverPhotoUrl')) {
    setState(() {
    coverPhotoUrl = data['coverPhotoUrl'] as String?;
    });
    print('Loaded cover photo URL: $coverPhotoUrl');
    } else {
    print('No cover photo URL found in Firestore document');
    }
    } else {
    print('Document does not exist. Creating a new one.');
    await docRef.set({
    'createdAt': FieldValue.serverTimestamp(),
    // Add any other initial fields you want for a new program
    });
    }
    } catch (e) {
    print('Error loading cover photo URL: $e');
    }
    }

    @override
    Widget build(BuildContext context) {
    return Scaffold(
    backgroundColor: Colors.white,
    body: StreamBuilder<QuerySnapshot>(
    stream: FirebaseFirestore.instance.collection('programs').snapshots(),
    builder: (context, snapshot) {
    if (snapshot.hasError) {
    return Center(child: Text('Error: ${snapshot.error}'));
    }

    if (snapshot.connectionState == ConnectionState.waiting) {
    return Center(child: CircularProgressIndicator());
    }

    if (snapshot.data!.docs.isEmpty) {
    return Center(child: Text('No programs available'));
    }

    DocumentSnapshot firstDocument = snapshot.data!.docs.first;
    Map<String, dynamic> firstData = firstDocument.data() as Map<String, dynamic>;

    return CustomScrollView(
    slivers: [
    SliverAppBar(
    expandedHeight: 300,
    floating: false,
    pinned: true,
    backgroundColor: Colors.transparent,
    flexibleSpace: FlexibleSpaceBar(
    background: Stack(
    fit: StackFit.expand,
    children: [
    if (coverPhotoUrl != null && coverPhotoUrl!.startsWith('http'))
    Image.network(
    coverPhotoUrl!,
    fit: BoxFit.cover,
    errorBuilder: (context, error, stackTrace) {
    print('Error loading image: $error');
    return Image.asset(
    'assets/cover_photo.jpg',
    fit: BoxFit.cover,
    );
    },
    )
    else if (_image != null)
    Image.file(
    _image!,
    fit: BoxFit.cover,
    )
    else
    Image.asset(
    'assets/cover_photo.jpg',
    fit: BoxFit.cover,
    ),
    Positioned(
    left: 16,
    right: 16,
    bottom: 16,
    child: Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: [
    Text(
    firstData['title'] ?? 'No title',
    style: TextStyle(
    fontSize: 24,
    fontWeight: FontWeight.bold,
    color: Colors.white,
    ),
    ),
    SizedBox(height: 8),
    Row(
    children: [
    Container(
    padding: EdgeInsets.symmetric(horizontal: 12, vertical: 6),
    decoration: BoxDecoration(
    color: Colors.grey.withOpacity(0.5),
    borderRadius: BorderRadius.circular(20),
    ),
    child: Text(
    firstData['category'] ?? 'N/A',
    style: TextStyle(color: Colors.white),
    ),
    ),
    SizedBox(width: 8),
    Container(
    padding: EdgeInsets.symmetric(horizontal: 12, vertical: 6),
    decoration: BoxDecoration(
    color: Colors.grey.withOpacity(0.5),
    borderRadius: BorderRadius.circular(20),
    ),
    child: Text(
    (firstData['days'] as List<dynamic>?)?.map((day) => day.toString()[0].toUpperCase()).join(' ') ?? 'N/A',
    style: TextStyle(color: Colors.white),
    ),
    ),
    ],
    ),
    ],
    ),
    ),
    ],
    ),
    ),
    leading: Padding(
    padding: const EdgeInsets.all(8.0),
    child: CircleAvatar(
    backgroundColor: Colors.grey.withOpacity(0.5),
    child: IconButton(
    icon: Icon(Icons.arrow_back, color: Colors.white),
    onPressed: () => Navigator.pop(context),
    ),
    ),
    ),
    actions: [
    Padding(
    padding: const EdgeInsets.all(8.0),
    child: ElevatedButton.icon(
    onPressed: _showBottomSheet,
    icon: Icon(Icons.edit, color: Colors.white),
    label: Text('Edit', style: TextStyle(color: Colors.white)),
    style: ElevatedButton.styleFrom(
    backgroundColor: Colors.black.withOpacity(0.5),
    shape: RoundedRectangleBorder(
    borderRadius: BorderRadius.circular(20),
    ),
    padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
    ),
    ),
    ),
    ],
    ),
    ],
    );
    },
    ),
    );
    }

    void _showBottomSheet() {
    showModalBottomSheet(
    context: context,
    isScrollControlled: true,
    backgroundColor: Colors.white,
    shape: RoundedRectangleBorder(
    borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
    ),
    builder: (BuildContext context) {
    return Padding(
    padding: EdgeInsets.only(
    bottom: MediaQuery.of(context).viewInsets.bottom,
    ),
    child: Container(
    padding: EdgeInsets.all(24),
    child: Column(
    mainAxisSize: MainAxisSize.min,
    children: [
    ElevatedButton(
    onPressed: () {
    print("Add cover photo button pressed");
    _pickImage();
    },
    child: Text(
    'Add cover photo',
    style: TextStyle(
    fontWeight: FontWeight.bold,
    fontSize: 16,
    ),
    ),
    style: ElevatedButton.styleFrom(
    backgroundColor: Colors.white,
    foregroundColor: Colors.black,
    padding: EdgeInsets.symmetric(horizontal: 24, vertical: 12),
    shape: RoundedRectangleBorder(
    borderRadius: BorderRadius.circular(30),
    ),
    elevation: 5,
    ),
    ),
    SizedBox(height: 24),
    Text(
    'Add more details about the workout',
    textAlign: TextAlign.center,
    style: TextStyle(
    fontSize: 20,
    fontWeight: FontWeight.bold,
    color: Colors.black,
    ),
    ),
    SizedBox(height: 16),
    Text(
    'Do you use any equipment for the workouts?',
    textAlign: TextAlign.center,
    style: TextStyle(
    fontSize: 16,
    color: Colors.black,
    ),
    ),
    SizedBox(height: 16),
    TextField(
    decoration: InputDecoration(
    hintText: 'eg: 2kg dumbbells, 3kg ball',
    border: OutlineInputBorder(),
    ),
    ),
    SizedBox(height: 24),
    Center(
    child: ElevatedButton(
    onPressed: () {
    // TODO: Implement save functionality
    Navigator.pop(context);
    },
    child: Text(
    'Save',
    style: TextStyle(
    fontWeight: FontWeight.bold,
    fontSize: 16,
    ),
    ),
    style: ElevatedButton.styleFrom(
    backgroundColor: Colors.black,
    foregroundColor: Colors.white,
    padding: EdgeInsets.symmetric(horizontal: 32, vertical: 16),
    shape: RoundedRectangleBorder(
    borderRadius: BorderRadius.circular(30),
    ),
    ),
    ),
    ),
    ],
    ),
    ),
    );
    },
    );
    }

    Future<void> _pickImage() async {
    print("_pickImage method started");
    try {
    final ImagePicker _picker = ImagePicker();
    print("Attempting to pick an image");
    final XFile? image = await _picker.pickImage(source: ImageSource.gallery);

    if (image != null) {
    print("Image picked: ${image.path}");
    setState(() {
    _image = File(image.path);
    // Don't set coverPhotoUrl here
    });

    // Upload the image and update Firestore
    await _uploadImage();

    // Show a success message
    ScaffoldMessenger.of(context).showSnackBar(
    SnackBar(content: Text('Cover photo updated successfully')),
    );
    } else {
    print('No image selected');
    }
    } catch (e) {
    print('Error picking image: $e');
    ScaffoldMessenger.of(context).showSnackBar(
    SnackBar(content: Text('Error selecting image: $e')),
    );
    }
    }

    Future<void> _uploadImage() async {
    if (_image == null) return;

    try {
    print('Starting image upload process');
    final storageRef = FirebaseStorage.instance.ref();
    final imageRef = storageRef.child('program_covers/${DateTime.now().millisecondsSinceEpoch}.jpg');

    print('Uploading to path: ${imageRef.fullPath}');

    final uploadTask = imageRef.putFile(_image!);
    final snapshot = await uploadTask.whenComplete(() => print('Upload completed'));

    final downloadURL = await snapshot.ref.getDownloadURL();
    print('Download URL obtained: $downloadURL');

    // Check if the document exists, if not, create it
    final docRef = FirebaseFirestore.instance.collection('programs').doc('your_program_id');
    final docSnapshot = await docRef.get();

    if (docSnapshot.exists) {
    await docRef.update({
    'coverPhotoUrl': downloadURL,
    });
    } else {
    await docRef.set({
    'coverPhotoUrl': downloadURL,
    // Add any other initial fields you want for a new program
    'createdAt': FieldValue.serverTimestamp(),
    });
    }

    print('Image uploaded and Firestore updated');
    setState(() {
    coverPhotoUrl = downloadURL;
    });

    // Reload the cover photo URL to ensure UI is updated
    await _loadCoverPhotoUrl();

    } catch (e) {
    print('Error in _uploadImage: $e');
    ScaffoldMessenger.of(context).showSnackBar(
    SnackBar(content: Text('Error uploading image: $e')),
    );
    }
    }
    }


    And here is where I try to display the cover photo again on MyProfileScreen()

    class _MyProfileScreenState extends State<MyProfileScreen> with SingleTickerProviderStateMixin {
    // ... existing code ...

    String? coverPhotoUrl;

    @override
    void initState() {
    super.initState();
    _tabController = TabController(length: 2, vsync: this);
    _loadCoverPhotoUrl();
    }

    Future<void> _loadCoverPhotoUrl() async {
    final programDoc = await FirebaseFirestore.instance.collection('programs').limit(1).get();
    if (programDoc.docs.isNotEmpty) {
    final programData = programDoc.docs.first.data();
    final coverPhotoPath = programData['coverPhotoPath'] as String?;
    if (coverPhotoPath != null) {
    try {
    final url = await FirebaseStorage.instance.ref(coverPhotoPath).getDownloadURL();
    setState(() {
    coverPhotoUrl = url;
    });
    } catch (e) {
    print('Error loading cover photo: $e');
    }
    }
    }
    }

    @override
    Widget build(BuildContext context) {
    // ... existing code ...

    return Scaffold(
    // ... existing code ...
    body: FutureBuilder<DocumentSnapshot>(
    future: _getUserData(),
    builder: (context, snapshot) {
    // ... existing code ...

    return Column(
    children: [
    // ... existing code ...
    Expanded(
    child: TabBarView(
    controller: _tabController,
    children: [
    // Workout Tab Content
    StreamBuilder<QuerySnapshot>(
    stream: FirebaseFirestore.instance.collection('programs').snapshots(),
    builder: (context, snapshot) {
    if (snapshot.connectionState == ConnectionState.waiting) {
    return Center(child: CircularProgressIndicator());
    }
    if (snapshot.hasError) {
    return Center(child: Text('Error: ${snapshot.error}'));
    }
    if (!snapshot.hasData || snapshot.data!.docs.isEmpty) {
    return Center(
    child: Text(
    'There is no workout content posted yet',
    style: TextStyle(
    fontSize: 16,
    color: Colors.grey[600],
    ),
    ),
    );
    }

    // Display the first workout program
    var program = snapshot.data!.docs.first;
    var programData = program.data() as Map<String, dynamic>;

    return Padding(
    padding: EdgeInsets.all(16),
    child: Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: [
    Stack(
    alignment: Alignment.center,
    children: [
    if (coverPhotoUrl != null)
    Image.network(
    coverPhotoUrl!,
    width: double.infinity,
    height: 200,
    fit: BoxFit.cover,
    errorBuilder: (context, error, stackTrace) {
    print('Error displaying image: $error');
    return Image.asset(
    'assets/cover_photo.jpg',
    width: double.infinity,
    height: 200,
    fit: BoxFit.cover,
    );
    },
    )
    else
    Image.asset(
    'assets/cover_photo.jpg',
    width: double.infinity,
    height: 200,
    fit: BoxFit.cover,
    ),
    Container(
    width: double.infinity,
    height: 200,
    decoration: BoxDecoration(
    gradient: LinearGradient(
    begin: Alignment.topCenter,
    end: Alignment.bottomCenter,
    colors: [
    Colors.transparent,
    Colors.black.withOpacity(0.7),
    ],
    stops: [0.5, 1.0],
    ),
    ),
    ),
    Positioned(
    left: 16,
    right: 16,
    bottom: 16,
    child: Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: [
    Text(
    programData['title'] ?? 'Untitled Program',
    style: TextStyle(
    fontSize: 20,
    fontWeight: FontWeight.bold,
    color: Colors.white,
    ),
    ),
    SizedBox(height: 8),
    ElevatedButton(
    onPressed: () {
    Navigator.push(
    context,
    MaterialPageRoute(builder: (context) => WorkoutContentAdded()),
    );
    },
    style: ElevatedButton.styleFrom(
    backgroundColor: Colors.white,
    foregroundColor: Colors.black,
    shape: RoundedRectangleBorder(
    borderRadius: BorderRadius.circular(8),
    ),
    padding: EdgeInsets.symmetric(horizontal: 20, vertical: 10),
    ),
    child: Text(
    'View Programs',
    style: TextStyle(
    fontWeight: FontWeight.bold,
    fontSize: 16,
    ),
    ),
    ),
    ],
    ),
    ),
    ],
    ),
    ],
    ),
    );
    },
    ),
    // ... Diet Tab Content ...
    ],
    ),
    ),
    ],
    );
    },
    ),
    );
    }

    // ... rest of the existing code ...
    }

    Continue reading...

Compartilhe esta Página