Search code examples
firebaseflutterfirebase-realtime-databaseflutter-streambuilder

Edit User Profile Page and Profile Picture. Using Real-Time Database flutter


I am trying to pull user data from my UserProfileBrowse Data model and display it on my user profile edit page. Including the image. I also want to update the data into my real-time Database. User Profile Edit Page Display

RealTime Database in firestore

THIS IS MY DATA MODEL

class UserProfileBrowse {
  String userId;
  int age;
  String name;
  String email;
  String imageUrl;

  UserProfileBrowse(
    this.userId,
    this.age,
    this.name,
    this.email,
    this.imageUrl,
  );

  Map<dynamic, dynamic> toJson() => <dynamic, dynamic>{
        'userId': userId,
        'age': age,
        'name': name,
        'email': email,
        'imageUrl' : imageUrl,
      };
}

THIS IS MY USER PROFILE EDIT PAGE

import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../services/auth.dart';
import 'home.dart';
import 'settings.dart';
import 'package:shadow_app_project/data_models/user_profile_browse.dart';
import 'package:shadow_app_project/image_selection/user_edit_image.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_database/firebase_database.dart';

class SettingsUI extends StatelessWidget {
  const SettingsUI({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      title: "Setting UI",
      home: EditProfilePage(),
    );
  }
}

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

  @override
  _EditProfilePageState createState() => _EditProfilePageState();
}

class _EditProfilePageState extends State<EditProfilePage> {

  String currentUser = (Auth().auth.currentUser as User).email.toString();
  TextEditingController displayNameController = TextEditingController();
  TextEditingController ageController = TextEditingController();
  bool isLoading = false;
  User? user;
  UserProfileBrowse? userModel;
  String? imageUrl;
  final refDatabase = FirebaseDatabase.instance;
  bool showPassword = false;
  @override
  Widget build(BuildContext context) {

    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).scaffoldBackgroundColor,
        elevation: 1,
        leading: IconButton(
          icon: const Icon(
            Icons.arrow_back,
            color: Colors.green,
          ),
          onPressed: () {
            Navigator.of(context).push(MaterialPageRoute(
                builder: (BuildContext context) => const SettingsPage()));
          },
        ),
        actions: [
          IconButton(
            icon: const Icon(
              Icons.settings,
              color: Colors.green,
            ),
            onPressed: () {
              Navigator.of(context).push(MaterialPageRoute(
                  builder: (BuildContext context) => const SettingsPage()));
            },
          ),
        ],
      ),
      body: Container(
        padding: const EdgeInsets.only(left: 16, top: 25, right: 16),
        child: GestureDetector(
          onTap: () {
            FocusScope.of(context).unfocus();
          },
          child: ListView(
            children: [
              const Text(
                "Edit Profile",
                style: TextStyle(fontSize: 25, fontWeight: FontWeight.w500),
              ),
              const SizedBox(
                height: 15,
              ),
              Container(
                width: 130,
                height: 130,
                decoration: BoxDecoration(
                    border: Border.all(
                        width: 4,
                        color: Theme.of(context).scaffoldBackgroundColor),
                    boxShadow: [
                      BoxShadow(
                          spreadRadius: 2,
                          blurRadius: 10,
                          color: Colors.black.withOpacity(0.1),
                          offset: const Offset(0, 10))
                    ],
                    shape: BoxShape.circle,
                    image: const DecorationImage(
                        fit: BoxFit.cover,
                        image: NetworkImage(
                          "https://images.pexels.com/photos/3307758/pexels-photo-3307758.jpeg?auto=compress&cs=tinysrgb&dpr=3&h=250",
                        ))),
              ),
              const SizedBox(
                height: 35,
              ),
              TextField(
                decoration: const InputDecoration(
                  labelText: "Name",
                  border: OutlineInputBorder(
                      borderSide: BorderSide(color: Colors.teal)),
                  hintText: 'Input Name',
                ),
                controller: displayNameController,
                keyboardType: TextInputType.name,
              ),
              TextField(
                decoration: const InputDecoration(
                  labelText: "Age",
                  border: OutlineInputBorder(
                      borderSide: BorderSide(color: Colors.teal)),
                  hintText: 'Input Age',
                ),
                controller: ageController,
                //
                keyboardType: TextInputType.number,
              ),
              const Padding(
                padding: EdgeInsets.all(8.0),
                child: Text("Email: ", style: TextStyle(fontSize: 20),),
              ),
              const SizedBox(
                height: 35,
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  TextButton(
                    onPressed: () {},
                    child: const Text("CANCEL",
                        style: TextStyle(
                            fontSize: 14,
                            letterSpacing: 2.2,
                            color: Colors.black)),
                  ),
                  TextButton(
                    onPressed: () {
                      FirebaseDatabase.instance.ref()
                          .child('useProfileBrowse')
                          .child(user!.uid)
                          .update({
                        'name': displayNameController.text //yes I know.
                      });
                      FirebaseDatabase.instance.ref()
                          .child('useProfileBrowse')
                          .child(user!.uid)
                          .update({
                        'age': ageController.text //yes I know.
                      });
                    },
                    child: const Text(
                      "SAVE",
                      style: TextStyle(
                          fontSize: 14,
                          letterSpacing: 2.2,
                          color: Colors.white),
                    ),
                  )
                ],
              )
            ],
          ),
        ),
      ),
    );
  }
}

I am thinking to use a StreamBuilder in my body: with stream: FirebaseDatabase.instance.ref().child('userProfileBrowse').child(user!.uid).onValue,

Any idea how can I display User profile Imageurl, name, and age from my real-time Database And also edit the information using stream builder or any other method

I have just coded the UI for my profile edit page. I just want someone to help me retrieve data from my data model class and display it on my user edit page. A single line to display just a name from my data model will help a lot to understand how retrieving data works. I have already saved data(imageUrl, name, age) into my data models during the signup process. Just want to display it


Solution

  • full example with StreamProvider :

    import 'dart:collection';
    import 'package:flutter/material.dart';
    import 'package:provider/provider.dart';
    
    class Person {
      Person({required this.name, required this.initialAge});
    
      final String name;
      final int initialAge;
    
      Stream<String> get age async* {
        var i = initialAge;
        while (i < 85) {
          await Future.delayed(const Duration(seconds: 1), () {
            i++;
          });
          yield i.toString();
        }
      }
    }
    
    void main() {
      runApp(
        StreamProvider<String>(
          create: (_) => Person(name: 'Yohan', initialAge: 25).age,
          initialData: 25.toString(),
          catchError: (_, error) => error.toString(),
          child: const MyApp(),
        ),
      );
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return const MaterialApp(
          home: MyHomePage(),
        );
      }
    }
    
    class MyHomePage extends StatelessWidget {
      const MyHomePage({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text("Future Provider"),
          ),
          body: Padding(
            padding: const EdgeInsets.all(8.0),
            child: Center(
              child: Consumer<String>(
                builder: (context, String age, child) {
                  return Column(
                    children: <Widget>[
                      const Text("Watch Yohan Age..."),
                      const Text("name: Yohan"),
                      Text("age: $age"),
                    ],
                  );
                },
              ),
            ),
          ),
        );
      }
    }