Home > Net >  All 4 fields have the same value in my Firestore database for my flutter app
All 4 fields have the same value in my Firestore database for my flutter app

Time:07-25

I am building a flutter application and I'm using Firebase to manage my users. I'm having problems storing the data(passwords) which the user enters on my app.

I enter different value in the 4 textfield. But when I view the data of the data of the 4 text fields on my app or the firestore database all the textfields have the same value.

The data that I enter on my app The data that I can view on the app The data stored on Firestore database

Code for Create,update,save,delete password.

import 'package:flutter/material.dart';
import 'package:secure_pass/services/auth/auth_service.dart';
import 'package:secure_pass/utilities/dialogs/cannot_share_empty_password_dialog.dart';
import 'package:secure_pass/utilities/generics/get_arguments.dart';
import 'package:secure_pass/services/cloud/cloud_password.dart';
import 'package:secure_pass/services/cloud/firebase_cloud_storage.dart';
import 'package:share_plus/share_plus.dart';

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

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

class _CreateUpdatePasswordViewState extends State<CreateUpdatePasswordView> {
  CloudPassword? _password;
  late final FirebaseCloudStorage _passwordsService;
  late final TextEditingController _emailController;
  late final TextEditingController _titleController;
  late final TextEditingController _userPasswordController;
  late final TextEditingController _urlController;

  @override
  void initState() {
    _passwordsService = FirebaseCloudStorage();
    _titleController = TextEditingController();
    _emailController = TextEditingController();
    _userPasswordController = TextEditingController();
    _urlController = TextEditingController();
    super.initState();
  }

  void _titleControllerListener() async {
    final password = _password;
    if (password == null) {
      return;
    }
    final title = _titleController.text;
    await _passwordsService.updatePassword(
      documentId: password.documentId,
      text: title,
    );
  }

  void _emailControllerListener() async {
    final password = _password;
    if (password == null) {
      return;
    }
    final email = _emailController.text;
    await _passwordsService.updatePassword(
      documentId: password.documentId,
      text: email,
    );
  }

  void _userPasswordControllerListener() async {
    final password = _password;
    if (password == null) {
      return;
    }
    final userpassword = _userPasswordController.text;
    await _passwordsService.updatePassword(
      documentId: password.documentId,
      text: userpassword,
    );
  }

  void _urlControllerListener() async {
    final password = _password;
    if (password == null) {
      return;
    }
    final url = _urlController.text;
    await _passwordsService.updatePassword(
      documentId: password.documentId,
      text: url,
    );
  }

  void _setupTextControllerListener() {
    _titleController.removeListener(_titleControllerListener);
    _titleController.addListener(_titleControllerListener);
    _emailController.removeListener(_emailControllerListener);
    _emailController.addListener(_emailControllerListener);
    _userPasswordController.removeListener(_userPasswordControllerListener);
    _userPasswordController.addListener(_userPasswordControllerListener);
    _urlController.removeListener(_urlControllerListener);
    _urlController.addListener(_urlControllerListener);
  }

  Future<CloudPassword> createOrGetExistingPassword(BuildContext context) async {
    final widgetPassword = context.getArgument<CloudPassword>();

    if (widgetPassword != null) {
      _password = widgetPassword;
      _titleController.text = widgetPassword.title;
      _emailController.text = widgetPassword.email;
      _userPasswordController.text = widgetPassword.userpassword;
      _urlController.text = widgetPassword.url;
      return widgetPassword;
    }

    final existingPassword = _password;
    if (existingPassword != null) {
      return existingPassword;
    }
    final currentUser = AuthService.firebase().currentUser!;
    final userId = currentUser.id;
    final newPassword = await _passwordsService.createNewPassword(ownerUserId: userId);
    _password = newPassword;
    return newPassword;
  }

  void _deletePasswordIfTextIsEmpty() {
    final password = _password;
    if (_titleController.text.isEmpty && _emailController.text.isEmpty && _userPasswordController.text.isEmpty && _urlController.text.isEmpty && password != null) {
      _passwordsService.deletePassword(documentId: password.documentId);
    }
  }

  void _savePasswordIfTextNotEmpty() async {
    final password = _password;
    final title = _titleController.text;
    final email = _emailController.text;
    final userpassword = _userPasswordController.text;
    final url = _urlController.text;
    if (password != null && title.isNotEmpty) {
      await _passwordsService.updatePassword(
        documentId: password.documentId,
        text: title,
      );
    }
    if (password != null && email.isNotEmpty) {
      await _passwordsService.updatePassword(
        documentId: password.documentId,
        text: email,
      );
    }
    if (password != null && userpassword.isNotEmpty) {
      await _passwordsService.updatePassword(
        documentId: password.documentId,
        text: userpassword,
      );
    }
    if (password != null && url.isNotEmpty) {
      await _passwordsService.updatePassword(
        documentId: password.documentId,
        text: url,
      );
    }
  }

  @override
  void dispose() {
    _deletePasswordIfTextIsEmpty();
    _savePasswordIfTextNotEmpty();
    _titleController.dispose();
    _emailController.dispose();
    _userPasswordController.dispose();
    _urlController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('New Password'),
        centerTitle: true,
        backgroundColor: Colors.purple[500],
        elevation: 0,
        actions: [
          IconButton(
            onPressed: () async {
              final text = _emailController.text;
              if (_password == null || text.isEmpty) {
                await showCannotShareEmptyPasswordDialog(context);
              } else {
                Share.share(text);
              }
            },
            icon: const Icon(Icons.share),
          ),
        ],
      ),
      body: FutureBuilder(
        future: createOrGetExistingPassword(context),
        builder: (context, snapshot) {
          switch (snapshot.connectionState) {
            case ConnectionState.done:
              _setupTextControllerListener();
              return Padding(
                padding: const EdgeInsets.symmetric(horizontal: 20.0, vertical: 10.0),
                child: Column(
                  children: [
                    //Title field
                    Container(
                      decoration: BoxDecoration(
                          color: Colors.white,
                          border: Border.all(color: Colors.white),
                          borderRadius: BorderRadius.circular(12),
                        ),
                      child: TextField(
                        controller: _titleController,
                        decoration: const InputDecoration(
                          hintText: 'Enter your title here',
                          border: OutlineInputBorder(),
                        ),
                      ),
                    ),
                    const SizedBox(height: 25),
                    //End of title field

                    //Email field
                    Container(
                      decoration: BoxDecoration(
                          color: Colors.white,
                          border: Border.all(color: Colors.white),
                          borderRadius: BorderRadius.circular(12),
                        ),
                      child: TextField(
                        controller: _emailController,
                        decoration: const InputDecoration(
                          hintText: 'Enter your email here',
                          border: OutlineInputBorder(),
                        ),
                      ),
                    ),
                    const SizedBox(height: 25),
                    //End of email field

                    //Password field
                    Container(
                      decoration: BoxDecoration(
                          color: Colors.white,
                          border: Border.all(color: Colors.white),
                          borderRadius: BorderRadius.circular(12),
                        ),
                      child: TextField(
                        controller: _userPasswordController,
                        decoration: const InputDecoration(
                          hintText: 'Enter your password here',
                          border: OutlineInputBorder(),
                        ),
                      ),
                    ),
                    const SizedBox(height: 25),
                    //End of password field

                    //URL field
                    Container(
                      decoration: BoxDecoration(
                          color: Colors.white,
                          border: Border.all(color: Colors.white),
                          borderRadius: BorderRadius.circular(12),
                        ),
                      child: TextField(
                        controller: _urlController,
                        decoration: const InputDecoration(
                          hintText: 'Enter your URL here',
                          border: OutlineInputBorder(),
                        ),
                      ),
                    ),
                    const SizedBox(height: 25),
                    //End of URL field
                  ],
                  
                ),
              );
            default:
              return const CircularProgressIndicator();
          }
        },
      ),
    );
  }
}

Code for cloud_password.dart

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:secure_pass/services/cloud/cloud_storage_constants.dart';
import 'package:flutter/foundation.dart';

@immutable
class CloudPassword {
  final String documentId;
  final String ownerUserId;
  final String title;
  final String email;
  final String userpassword;
  final String url;
  const CloudPassword({
    required this.documentId,
    required this.ownerUserId,
    required this.title,
    required this.email,
    required this.userpassword,
    required this.url,
  });

  CloudPassword.fromSnapshot(QueryDocumentSnapshot<Map<String, dynamic>> snapshot)
      : documentId = snapshot.id,
        ownerUserId = snapshot.data()[ownerUserIdFieldName],
        title = snapshot.data()[titleFieldName] as String,
        email = snapshot.data()[emailFieldName] as String,
        userpassword = snapshot.data()[userpasswordFieldName] as String,
        url = snapshot.data()[urlFieldName] as String;
        
}

Code for cloud_storage_constants.dart

const ownerUserIdFieldName = 'user_id';
const titleFieldName = 'title';
const emailFieldName = 'email';
const userpasswordFieldName = 'userpassword';
const urlFieldName = 'url';

Code for firebase_cloud_storage.dart

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:secure_pass/services/cloud/cloud_password.dart';
import 'package:secure_pass/services/cloud/cloud_storage_constants.dart';
import 'package:secure_pass/services/cloud/cloud_storage_exceptions.dart';

class FirebaseCloudStorage {
  final passwords = FirebaseFirestore.instance.collection('passwords');

  Future<void> deletePassword({required String documentId}) async {
    try {
      await passwords.doc(documentId).delete();
    } catch (e) {
      throw CouldNotDeletePasswordException();
    }
  }

  Future<void> updatePassword({
    required String documentId,
    required String text,
  }) async {
    try {
      await passwords.doc(documentId).update({titleFieldName: text});
      await passwords.doc(documentId).update({emailFieldName: text});
      await passwords.doc(documentId).update({userpasswordFieldName: text});
      await passwords.doc(documentId).update({urlFieldName: text});
    } catch (e) {
      throw CouldNotUpdatePasswordException();
    }
  }

  Stream<Iterable<CloudPassword>> allPasswords({required String ownerUserId}) =>
      passwords.snapshots().map((event) => event.docs
          .map((doc) => CloudPassword.fromSnapshot(doc))
          .where((password) => password.ownerUserId == ownerUserId));

  Future<Iterable<CloudPassword>> getPasswords({required String ownerUserId}) async {
    try {
      return await passwords
          .where(
            ownerUserIdFieldName,
            isEqualTo: ownerUserId,
          )
          .get()
          .then(
            (value) => value.docs.map((doc) => CloudPassword.fromSnapshot(doc)),
          );
    } catch (e) {
      throw CouldNotGetAllPasswordsException();
    }
  }

  Future<CloudPassword> createNewPassword({required String ownerUserId}) async {
    final document = await passwords.add({
      ownerUserIdFieldName: ownerUserId,
      titleFieldName: '',
      emailFieldName: '',
      userpasswordFieldName: '',
      urlFieldName: '',
    });
    final fetchedPassword = await document.get();
    return CloudPassword(
      documentId: fetchedPassword.id,
      ownerUserId: ownerUserId,
      title: '',
      email: '',
      userpassword: '',
      url: '',
    );
  }

  static final FirebaseCloudStorage _shared =
      FirebaseCloudStorage._sharedInstance();
  FirebaseCloudStorage._sharedInstance();
  factory FirebaseCloudStorage() => _shared;
}

Can someone tell me what mistake I have done please.

CodePudding user response:

Your code puts the same value text in each document field:

      await passwords.doc(documentId).update({titleFieldName: text});
      await passwords.doc(documentId).update({emailFieldName: text});
      await passwords.doc(documentId).update({userpasswordFieldName: text});
      await passwords.doc(documentId).update({urlFieldName: text});

Maybe you want to instead use a single function that receives all of separate values to write, and performs a single document update with all of those values in the same way that you initially created the document.

  • Related