【问题标题】:Not able to store data into Firestore无法将数据存储到 Firestore
【发布时间】:2021-08-23 10:07:23
【问题描述】:
I'm writing a code to login and Register with user email and password. And I'm trying to store that data into firestore and firebase storage.

我将注册人的图像存储到 Firebase 存储中。以及其他详细信息到 Firestore,如姓名、电子邮件等。现在图像将进入 firebaseStorage,但应该存储在 firestore 中的其他信息不会进入 firestore。

错误:

正在对注册用户进行身份验证

个人资料图片上传成功

但是FireStore存储是空的,这里没有注册用户的详细信息。

颤振医生

Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel stable, 2.2.3, on Microsoft Windows [Version 10.0.19043.1200], locale en-PK)
[√] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
[√] Chrome - develop for the web
[√] Android Studio (version 4.1.0)
[√] Connected device (2 available)

• No issues found!

pub.yaml

name: ecom_app
description: A new Flutter project.

publish_to: 'none' # Remove this line if you wish to publish to pub.dev

version: 1.0.0+1

environment:
  sdk: ">=2.12.0 <3.0.0"

dependencies:
  flutter:
    sdk: flutter
  cloud_firestore: ^2.5.0
  firebase_auth: ^3.0.2
  firebase_core: ^1.5.0
  shared_preferences: ^2.0.6
  fluttertoast: ^8.0.8
  image_picker: ^0.8.3+2
  firebase_storage: ^10.0.2
  flutter_staggered_grid_view: ^0.4.0
  provider: ^6.0.0
  path_provider: ^2.0.2
  image: ^3.0.2
  intl: ^0.17.0

  cupertino_icons: ^1.0.2

dev_dependencies:
  flutter_test:
    sdk: flutter

# The following section is specific to Flutter.
flutter:
  uses-material-design: true

  # To add assets to your application, add an assets section, like this:
  assets:
    - images/
  #   - images/a_dot_ham.jpeg

Config.dart(这里我在 EcommerceApp 类中声明了所有需要的值

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:shared_preferences/shared_preferences.dart';
class EcommerceApp{
  static const String appName='E-shop';
  static SharedPreferences sharedPreferences=SharedPreferences.getInstance() as SharedPreferences;
  static FirebaseAuth auth=FirebaseAuth.instance;
  static User user=FirebaseAuth.instance as User;
  static FirebaseFirestore firestore=FirebaseFirestore.instance;

  static String collectionUser='users';
  static String  collectionOrder='orders';
  static String  userCartList='usercart';
  static String  subCollectionAddress='userAddress';

  static final String userName='name';
  static final String userEmail ='email';
  static final String userPhotoUrl='photoUrl';
  static final String userId ='userid';
  static final String userAvatarUrl='avatarUrl';
  static final String addressId='addressId';
  static final String totalAmount='totalAmount';
  static final String productId='productId';
  static final String paymentDetails='paymentDetails';
  static final String orderTime='orderTime';
  static final String isSucces='isSucces';

}

Registerpage.dart(注册新用户,代码没有错误但Informaton没有存储在firestore中)

import 'dart:io';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:ecom_app/Config/config.dart';
import 'package:ecom_app/DialogBox/errordialog.dart';
import 'package:ecom_app/DialogBox/loadingDialog.dart';
import 'package:ecom_app/Store/StoreHomePage.dart';
import 'package:ecom_app/Widgets/CustomTextField.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
class Registration extends StatefulWidget {
  const Registration({Key? key}) : super(key: key);

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

class _RegistrationState extends State<Registration> {
  final TextEditingController _nameController =TextEditingController();
  final TextEditingController _emailController =TextEditingController();
  final TextEditingController _passwordController =TextEditingController();
  final TextEditingController _cpasswordController =TextEditingController();
  final GlobalKey<FormState> _formKey=GlobalKey<FormState>();
  String userImageUrl='';
  File? _imagefile;
  @override
  Widget build(BuildContext context) {
    double _screenwidth=MediaQuery.of(context).size.width,_screenHeight=MediaQuery.of(context).size.height;
    return SingleChildScrollView(
      child: Container(
        child: Column(
          mainAxisSize: MainAxisSize.max,
          children: [
            SizedBox(
              height: 10.0,
            ),
            Container(
             height: _screenHeight*0.25,
              width: _screenwidth*0.25,
              child:Column(
                children: [
                  Spacer(),
                  _imagefile !=null ? Image.file(_imagefile!):

                  CircleAvatar(
                    radius: _screenwidth * 0.15,
                    child: Icon(Icons.add_photo_alternate,size: _screenHeight*0.15
                        ,color: Colors.grey),
                  ),
                ],
              )

            ),
            /*InkWell(
              onTap: ()=>_PickImage(),

              ),*/

            SizedBox(
              height: 8.0,
            ),
            ElevatedButton(
                onPressed: ()=>_PickImage(),
                child:Icon(Icons.camera)
            ),
            SizedBox(
              height: 8.0,
            ),
            Form(
              key: _formKey,
                child: Column(
                  children: [
                    customtextfield(
                      controller: _nameController,
                      data: Icons.person,
                      hinttext: 'Name',
                      isObsecure:false
                    ),
                    customtextfield(
                        controller: _emailController,
                        data: Icons.email,
                        hinttext: 'Email',
                        isObsecure:false,
                    ),
                    customtextfield(
                        controller: _passwordController,
                        data: Icons.lock,
                        hinttext: 'Password',
                        isObsecure:true,
                    ),
                    customtextfield(
                        controller: _cpasswordController,
                        data: Icons.security,
                        hinttext: 'Confirm Password',
                        isObsecure: true,
                    ),
                  ],
                )
            ),
            ElevatedButton(
                onPressed: ()=>_uploadandSaveImage(),
                style: ElevatedButton.styleFrom(primary: Colors.pink,onPrimary: Colors.deepPurple),
                child:Text("Sign up"),
            ),
            SizedBox(
              height: 30.0,
            ),
            Container(
              height: 4.0,
              width: _screenwidth*0.8,
              color: Colors.pink,
            ),
            SizedBox(
              height: 15.0,
            )
          ],
        ),
      ),
    );
  }
  Future<void> _PickImage() async{
    final _imagefile =await ImagePicker().pickImage(source: ImageSource.camera);
    final _imageselected=File(_imagefile!.path);
    setState(() {
      this._imagefile=_imageselected;
    });


  }
  Future<void>_uploadandSaveImage() async{
  if(_imagefile == null)
      {
        showDialog(
            context: context,
            builder: (c)
            {
              return ErrorDialog(message: 'Please Select an Image');
            }
        );
      }
    else
      {
        _passwordController.text==_cpasswordController.text
            ? _nameController.text.isNotEmpty &&
    _emailController.text.isNotEmpty&&
    _passwordController.text.isNotEmpty&&
    _cpasswordController.text.isNotEmpty

            ? uploadToFirebaseStorage()

            : displayDialog('Field Can Not Be Empty!...')
            : displayDialog('Password Does Not Match');
      }

  }
  displayDialog(String msg) async{
    showDialog(
        context: context,
        builder: (c)
        {
          return ErrorDialog(message: msg);
        }
    );
  }
  uploadToFirebaseStorage()
  async {
    showDialog(
        context: context, builder: (c){
         return LoadingAlertDialog(message: 'Authentication Pleas wait...' );
    }
    );

    String imageFileName =DateTime.now().microsecondsSinceEpoch.toString();
    Reference storageReference=FirebaseStorage.instance.ref().child(imageFileName);
    UploadTask storageUploadTask=storageReference.putFile(_imagefile!);
    TaskSnapshot taskSnapshot=await storageUploadTask.whenComplete(() => null);
    await taskSnapshot.ref.getDownloadURL().then((urlImage){
      userImageUrl=urlImage;
      _registerUser();
    });

  }
  FirebaseAuth _auth=FirebaseAuth.instance;
   void _registerUser() async{
    User? firebaseuser;
    await _auth.createUserWithEmailAndPassword(
        email: _emailController.text.trim(),
        password: _passwordController.text.trim(),
    ).then((auth)
        {
          firebaseuser=auth.user!;
        }).catchError((error){
         Navigator.pop(context);
         showDialog(context: context, builder: (c)
         {
           return ErrorDialog(message: error.message.toString());
         });

    });

    if(firebaseuser != null)
      {
        savetoFirestore(firebaseuser!).then((value){
          Navigator.pop(context);
          Route route=MaterialPageRoute(builder: (c)=> StoreHome());
          Navigator.pushReplacement(context, route);
        });
      }
  }

  savetoFirestore(User fuser) async{
     FirebaseFirestore.instance.collection('users').doc(fuser.uid).set(
       {
        'uid':fuser.uid,
        'email': fuser.email,
         'name':_nameController.text.trim(),
         'url':userImageUrl,
         EcommerceApp.userCartList:['garbageValue'],
       }
     );
     await EcommerceApp.sharedPreferences.setString('uid', fuser.uid);
     await EcommerceApp.sharedPreferences.setString(EcommerceApp.userEmail, fuser.email!);
     await EcommerceApp.sharedPreferences.setString(EcommerceApp.userName, _nameController.text.trim());
     await EcommerceApp.sharedPreferences.setString(EcommerceApp.userAvatarUrl, userImageUrl);
     await EcommerceApp.sharedPreferences.setStringList(EcommerceApp.userCartList,['garbageValue']);
  }
}

错误更新:

【问题讨论】:

  • 您的 save to firestore 函数似乎没有被调用,请尝试在 .then 命令之前、期间和之后将打印函数放入其中。还可以尝试在代码中上树查看最后执行的命令
  • 我理解你的意思,但你能否通过更改我提供的代码来说明这一点。如果你能告诉我我必须把那些对我很有帮助的打印功能放在哪里。

标签: firebase flutter dart google-cloud-firestore user-registration


【解决方案1】:

在将用户信息存储到Firestore 之前,您有一个条件检查firebaseuser 变量是否不为空。

firebaseuser 变量为空,因为它位于创建用户后添加的.then 块之外。

解决方案:

您应该将条件移动到 .then 块内,以便在检查条件时 firebaseuser 变量不为空。

这是更改的代码:

void _registerUser() async {
    User? firebaseuser;
    await _auth
        .createUserWithEmailAndPassword(
      email: _emailController.text.trim(),
      password: _passwordController.text.trim(),
    )
        .then((auth) {
      firebaseuser = auth.user!;

      if (firebaseuser != null) {
        savetoFirestore(firebaseuser!).then((value) {
          Navigator.pop(context);
          Route route = MaterialPageRoute(builder: (c) => StoreHome());
          Navigator.pushReplacement(context, route);
        });
      }
    }).catchError((error) {
      Navigator.pop(context);
      showDialog(
          context: context,
          builder: (c) {
            return ErrorDialog(message: error.message.toString());
          });
    });
}

更新:

SharedPreferences.getInstance() 返回 Future&lt;SharedPreferences&gt; 而不是 SharedPreferences

您应该通过更新以下代码来修复共享首选项错误:

  • sharedPreferences 变量声明为 Future 类型。

    class EcommerceApp{
      static Future<SharedPreferences> sharedPreferences=SharedPreferences.getInstance();
      ...
    }
    
  • 等待EcommerceApp.sharedPreferences 变量,然后再对其进行任何操作。对您的 savetoFirestore 方法进行以下更改:

    savetoFirestore(User fuser) async{
     SharedPreferences sharedPreferences = await EcommerceApp.sharedPreferences;
    
     await sharedPreferences.setString('uid', fuser.uid);
     await sharedPreferences.setString(EcommerceApp.userEmail, fuser.email!);
     await sharedPreferences.setString(EcommerceApp.userName, _nameController.text.trim());
     await sharedPreferences.setString(EcommerceApp.userAvatarUrl, userImageUrl);
     await sharedPreferences.setStringList(EcommerceApp.userCartList,['garbageValue']);
    }
    

【讨论】:

  • 我用你做的函数试过了,但结果是一样的。 Firestore 中没有数据。
  • 控制台有错误信息吗?
  • 不是红线而是白线显示“ [ERROR:flutter/lib/ui/ui_dart_state.cc(199)] Unhandled Exception: type 'Future' is not a subtype类型转换中的“SharedPreferences”类型“'W/GooglePlayServicesUtil(10080): Google Play Store is missing。” 'E/GooglePlayServicesUtil(10080): GooglePlayServices not available due to error 9', "java.lang.AssertionError: Method getAlpnSelectedProtocol not supported for object SSL socket over Socket[address=firestore.googleapis.com/172.217.19.10,port=443 ,localPort=37638]" 有很多这样的行...
  • SharedPreferences 错误指的是哪一行?
  • 根据堆栈首先它在 Config.dart 文件中,我在 EcommerceApp 类中第一次声明了 sharedpreference。然后在 Register.dart 文件中,'savetofirestore' 函数,我在 uid、电子邮件等中使用了 5 次 sharedprefrences。然后在 _registeruser 函数中,因为 savetofirestore 函数被调用。
【解决方案2】:

终于找到了答案,我尝试了多种方法,但必须是Cloud Firestore的权限规则。我不知道它是否适用于所有人,但对我有用。我建议也使用上述所有已回答的解决方案。 但这在模拟器上不起作用。当我使用我的实际 Android 手机时,它就可以工作了。 这些是我在这里找到的规则 Failed to update ssl context

service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if true;
}}}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-17
    • 1970-01-01
    • 1970-01-01
    • 2020-04-18
    • 2021-12-23
    • 2020-09-26
    • 2018-06-11
    相关资源
    最近更新 更多