文档路径必须是一个非空字符串,颤音 - firebase错误?

发布于 2025-01-26 09:25:15 字数 6985 浏览 4 评论 0原文

我在颤音和燃烧案中遇到了一些错误,如果有人可以提供帮助,这是我的auth Controller,

class AuthController extends GetxController {
  final FirebaseAuth auth = FirebaseAuth.instance;
  final Rxn<User> _firebaseUser = Rxn<User>();
  Rx<XFile>? _pickedImage;

  XFile? get profilePhoto => _pickedImage?.value;
  // final user = FirebaseAuth.instance.currentUser.obs;

  Rxn<User> get user => _firebaseUser;
  // final user = FirebaseAuth.instance.currentUser;

  @override
  onInit() {
    _firebaseUser.bindStream(auth.authStateChanges());
    super.onInit();
  }

  // void register(
  //     String name, String email, String password, XFile? image) async {
  //   try {
  //     UserCredential _authResult = await auth.createUserWithEmailAndPassword(
  //         email: email.trim(), password: password);

  //     //create user in database.dart

  //     String downloadUrl = await uploadToStorage(image!);

  //     UserModel _user = UserModel(
  //       id: _authResult.user?.uid,
  //       name: name,
  //       email: _authResult.user?.email,
  //       profilePic: downloadUrl,
  //     );

  //     if (await Database().createNewUser(_user)) {
  //       Get.find<UserController>().user = _user;
  //     }
  //   } catch (e) {
  //     Get.snackbar(
  //       "Error creating Account",
  //       e.toString(),
  //       snackPosition: SnackPosition.BOTTOM,
  //     );
  //   }
  // }
  void register(
      String name, String email, String password, XFile? image) async {
    try {
      if (name.isNotEmpty &&
          email.isNotEmpty &&
          password.isNotEmpty &&
          image != null) {
        // save out user to our ath and firebase firestore
        UserCredential _authResult = await auth.createUserWithEmailAndPassword(
          email: email,
          password: password,
        );
        String downloadUrl = await uploadToStorage(image);
        UserModel _user = UserModel(
          id: _authResult.user?.uid,
          name: name,
          email: _authResult.user?.email,
          profilePic: downloadUrl,
        );
        if (await Database().createNewUser(_user)) {
          Get.find<UserController>().user = _user;
        } else {
          Get.snackbar(
            'Error Creating Account',
            'Please enter all the fields',
          );
        }
      }
    } catch (e) {
      Get.snackbar(
        'Error Creating Account',
        e.toString(),
      );
    }
  }

  void login(String email, password) async {
    try {
      UserCredential _authResult = await auth.signInWithEmailAndPassword(
          email: email.trim(), password: password);
      Get.find<UserController>().user =
          await Database().getUser(_authResult.user?.uid ?? '');
    } catch (e) {
      Get.snackbar("About User", "User message",
          snackPosition: SnackPosition.BOTTOM,
          titleText: Text("Acount creation failed"),
          messageText:
              Text(e.toString(), style: TextStyle(color: Colors.white)));
    }
  }

  Future<void> signOut() async {
    await auth.signOut();
    Get.find<UserController>().clear();
  }

  Future pickImage() async {
    print("call on click add photo icon");
    final ImagePicker _picker = ImagePicker();
    final XFile? pickedImage =
        await _picker.pickImage(source: ImageSource.gallery);
    print('picked image filled with image from gallery'); //This doesnt print at

    if (pickedImage != null) {
      Get.snackbar('Profile Picture',
          'You have successfully selected your profile picture!');

      // print(pickedImage.path);
    }
    _pickedImage = Rx<XFile>(pickedImage!);
    // print(_pickedImage);
    // print(profilePhoto);
  }

  // upload to firebase storage
  Future<String> uploadToStorage(XFile? image) async {
    Reference ref = FirebaseStorage.instance
        .ref('')
        .child('profilePics')
        .child(auth.currentUser!.uid);

    // print(ref);

    UploadTask uploadTask = ref.putFile(File(image?.path ?? 'idemo'));
    print(uploadTask);
    // TaskSnapshot snap = await uploadTask;
    String downloadUrl = await (await uploadTask).ref.getDownloadURL();
    print(downloadUrl);
    return downloadUrl;
  }
}

这是我在这里创建的功能

class Database {
  final FirebaseFirestore _firestore = FirebaseFirestore.instance;

  Future<bool> createNewUser(UserModel user) async {
    try {
      await _firestore.collection("users").doc(user.id).set({
        "name": user.name,
        "email": user.email,
        "profilePhoto": user.profilePic
      });
      return true;
    } catch (e) {
      print(e);
      return false;
    }
  }

,这里是HomeController

class HomeController extends GetxController {
  final Rxn<List<TodoModel>> todoList = Rxn<List<TodoModel>>([]);

  var selectedDate = DateTime.now().obs;

  List<TodoModel>? get todos => todoList.value;

  @override
  void onInit() {
    super.onInit();
    String? uid = Get.find<AuthController>().auth.currentUser?.uid ?? '';
    print(uid);
    todoList.bindStream(Database().todoStream(uid));
  }

  chooseDate() async {
    DateTime? pickedDate = await showDatePicker(
      context: Get.context!,
      initialDate: selectedDate.value,
      firstDate: DateTime(2000),
      lastDate: DateTime(2024),
      //initialEntryMode: DatePickerEntryMode.input,
      // initialDatePickerMode: DatePickerMode.year,
    );
    if (pickedDate != null && pickedDate != selectedDate.value) {
      selectedDate.value = pickedDate;
    }
  }
}

,这里是查看页面,

GetX<HomeController>(
  init: Get.put<HomeController>(HomeController()),
  builder: (HomeController todoController) {
    if (todoController.todos != null) {
      // print(todoController.todos?.done ?? false);
      return Expanded(
        child: ListView.builder(
          itemCount: todoController.todos?.length,
          itemBuilder: (_, index) {
            return TodoCard(
              uid: controller.user.value?.uid ?? '',
              todo: todoController.todos![index],
            );
          },
        ),
      );
    } else {
      return Text("loading...");
    }
  },
),

所以我有一个错误,当我注册新用户时,我得到了这个错误。错误:

以下断言是抛出建筑物建造者(肮脏): 文档路径必须是非空字符串 失败断言:第116行POS 14:'path.isnotempty'

此处是从终端输出的:

The relevant error-causing widget was
GetMaterialApp
lib/main.dart:23
When the exception was thrown, this was the stack
#2      _JsonCollectionReference.doc
#3      Database.todoStream
#4      HomeController.onInit
#5      GetLifeCycleBase._onStart
#6      InternalFinalCallback.call
#7      GetInstance._startController
#8      GetInstance._initDependencies
#9      GetInstance.find
#10     GetInstance.put
#11     Inst.put

因此,此路径的问题是一个问题,当我从视觉工作室重新加载时,我会使用正确的数据来适合正确的用户。因此,问题是当我第一次注册用户时。

I have some mistakes with flutter and firebase, if someone can help would be great here is my auth controller

class AuthController extends GetxController {
  final FirebaseAuth auth = FirebaseAuth.instance;
  final Rxn<User> _firebaseUser = Rxn<User>();
  Rx<XFile>? _pickedImage;

  XFile? get profilePhoto => _pickedImage?.value;
  // final user = FirebaseAuth.instance.currentUser.obs;

  Rxn<User> get user => _firebaseUser;
  // final user = FirebaseAuth.instance.currentUser;

  @override
  onInit() {
    _firebaseUser.bindStream(auth.authStateChanges());
    super.onInit();
  }

  // void register(
  //     String name, String email, String password, XFile? image) async {
  //   try {
  //     UserCredential _authResult = await auth.createUserWithEmailAndPassword(
  //         email: email.trim(), password: password);

  //     //create user in database.dart

  //     String downloadUrl = await uploadToStorage(image!);

  //     UserModel _user = UserModel(
  //       id: _authResult.user?.uid,
  //       name: name,
  //       email: _authResult.user?.email,
  //       profilePic: downloadUrl,
  //     );

  //     if (await Database().createNewUser(_user)) {
  //       Get.find<UserController>().user = _user;
  //     }
  //   } catch (e) {
  //     Get.snackbar(
  //       "Error creating Account",
  //       e.toString(),
  //       snackPosition: SnackPosition.BOTTOM,
  //     );
  //   }
  // }
  void register(
      String name, String email, String password, XFile? image) async {
    try {
      if (name.isNotEmpty &&
          email.isNotEmpty &&
          password.isNotEmpty &&
          image != null) {
        // save out user to our ath and firebase firestore
        UserCredential _authResult = await auth.createUserWithEmailAndPassword(
          email: email,
          password: password,
        );
        String downloadUrl = await uploadToStorage(image);
        UserModel _user = UserModel(
          id: _authResult.user?.uid,
          name: name,
          email: _authResult.user?.email,
          profilePic: downloadUrl,
        );
        if (await Database().createNewUser(_user)) {
          Get.find<UserController>().user = _user;
        } else {
          Get.snackbar(
            'Error Creating Account',
            'Please enter all the fields',
          );
        }
      }
    } catch (e) {
      Get.snackbar(
        'Error Creating Account',
        e.toString(),
      );
    }
  }

  void login(String email, password) async {
    try {
      UserCredential _authResult = await auth.signInWithEmailAndPassword(
          email: email.trim(), password: password);
      Get.find<UserController>().user =
          await Database().getUser(_authResult.user?.uid ?? '');
    } catch (e) {
      Get.snackbar("About User", "User message",
          snackPosition: SnackPosition.BOTTOM,
          titleText: Text("Acount creation failed"),
          messageText:
              Text(e.toString(), style: TextStyle(color: Colors.white)));
    }
  }

  Future<void> signOut() async {
    await auth.signOut();
    Get.find<UserController>().clear();
  }

  Future pickImage() async {
    print("call on click add photo icon");
    final ImagePicker _picker = ImagePicker();
    final XFile? pickedImage =
        await _picker.pickImage(source: ImageSource.gallery);
    print('picked image filled with image from gallery'); //This doesnt print at

    if (pickedImage != null) {
      Get.snackbar('Profile Picture',
          'You have successfully selected your profile picture!');

      // print(pickedImage.path);
    }
    _pickedImage = Rx<XFile>(pickedImage!);
    // print(_pickedImage);
    // print(profilePhoto);
  }

  // upload to firebase storage
  Future<String> uploadToStorage(XFile? image) async {
    Reference ref = FirebaseStorage.instance
        .ref('')
        .child('profilePics')
        .child(auth.currentUser!.uid);

    // print(ref);

    UploadTask uploadTask = ref.putFile(File(image?.path ?? 'idemo'));
    print(uploadTask);
    // TaskSnapshot snap = await uploadTask;
    String downloadUrl = await (await uploadTask).ref.getDownloadURL();
    print(downloadUrl);
    return downloadUrl;
  }
}

Here is my function to createNewUser

class Database {
  final FirebaseFirestore _firestore = FirebaseFirestore.instance;

  Future<bool> createNewUser(UserModel user) async {
    try {
      await _firestore.collection("users").doc(user.id).set({
        "name": user.name,
        "email": user.email,
        "profilePhoto": user.profilePic
      });
      return true;
    } catch (e) {
      print(e);
      return false;
    }
  }

Here is HomeController

class HomeController extends GetxController {
  final Rxn<List<TodoModel>> todoList = Rxn<List<TodoModel>>([]);

  var selectedDate = DateTime.now().obs;

  List<TodoModel>? get todos => todoList.value;

  @override
  void onInit() {
    super.onInit();
    String? uid = Get.find<AuthController>().auth.currentUser?.uid ?? '';
    print(uid);
    todoList.bindStream(Database().todoStream(uid));
  }

  chooseDate() async {
    DateTime? pickedDate = await showDatePicker(
      context: Get.context!,
      initialDate: selectedDate.value,
      firstDate: DateTime(2000),
      lastDate: DateTime(2024),
      //initialEntryMode: DatePickerEntryMode.input,
      // initialDatePickerMode: DatePickerMode.year,
    );
    if (pickedDate != null && pickedDate != selectedDate.value) {
      selectedDate.value = pickedDate;
    }
  }
}

and here is View page

GetX<HomeController>(
  init: Get.put<HomeController>(HomeController()),
  builder: (HomeController todoController) {
    if (todoController.todos != null) {
      // print(todoController.todos?.done ?? false);
      return Expanded(
        child: ListView.builder(
          itemCount: todoController.todos?.length,
          itemBuilder: (_, index) {
            return TodoCard(
              uid: controller.user.value?.uid ?? '',
              todo: todoController.todos![index],
            );
          },
        ),
      );
    } else {
      return Text("loading...");
    }
  },
),

So, I have an error when I register a new user I got this error:

The following assertion was thrown building Builder(dirty):
a document path must be a non-empty string
Failed assertion: line 116 pos 14: ‘path.isNotEmpty’

And here is output from terminal:

The relevant error-causing widget was
GetMaterialApp
lib/main.dart:23
When the exception was thrown, this was the stack
#2      _JsonCollectionReference.doc
#3      Database.todoStream
#4      HomeController.onInit
#5      GetLifeCycleBase._onStart
#6      InternalFinalCallback.call
#7      GetInstance._startController
#8      GetInstance._initDependencies
#9      GetInstance.find
#10     GetInstance.put
#11     Inst.put

So a problem is with this path, and when I reload from the visual studio I god the right user with the right data. So the problem is when I register a user for the first time.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

云雾 2025-02-02 09:25:15

看起来uid是空的,您还应该能够从输出中查找print(uid);中看到。

当您的应用程序或网页加载时,Firebase会自动尝试从其本地状态恢复以前签名的用户。但是,这要求它拨打服务器的呼叫(例如,检查帐户是否已被禁用),并且在呼叫进行时,您的主代码继续执行,并且currentuser变量正在进行为null

您的代码需要考虑到这一点。最简单的方法是不依赖currentuser,而是用反应性地响应身份验证状态的变化,如获得当前的用户

FirebaseAuth.instance
  .authStateChanges()
  .listen((User? user) {
    if (user != null) {
      print(user.uid);
    }
  });

auth> authstateChange每当身份验证状态变化时,这会发射事件,因此当用户登录或登录时。使用此流的常见方法是将用户设置为小部件的状态,或者直接在streamBuilder中使用该流。

It looks like uid is empty, which you should also be able to see from looking up print(uid); in your output.

When your application or web page loads, Firebase automatically tries to restore the previously signed in user from its local state. This requires that it makes a call to the server however (for example to check if the account has been disabled) and while that call is going on, your main code continues to execute and the currentUser variable is going to be null.

Your code needs to take this into account. The easiest way to do this is to not depend on currentUser, but instead to use an reactively respond to changes in the authentication state as shown in the first example in the documentation on getting the current user:

FirebaseAuth.instance
  .authStateChanges()
  .listen((User? user) {
    if (user != null) {
      print(user.uid);
    }
  });

The authStateChange method here returns a stream that fires an event whenever the authentication state changes, so when the user signs in or signs out. The common way to use this stream is to either set the user to the state of your widget, or to use the stream directly in a StreamBuilder.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文