Хранилище Flutter Fire — Назначение переменных отдельным полям документа

# #flutter #google-cloud-firestore

Вопрос:

Я пытаюсь показать изображение профиля пользователя на его домашней странице, вытащив «ImageUrl» пользователя из документа Fire Store. У меня уже есть настройка приложения, в котором пользователь может загрузить новое изображение, которое обновляет «ImageUrl» в магазине Fire, но я не знаю, как использовать «ImageUrl» в качестве переменной, чтобы я мог показать его на экране приложения.

Я читал документацию в Интернете, но она кажется чрезмерно упрощенной или устаревшей. Я пробовал использовать StreamBuilder, но он извлекает данные от каждого пользователя в базе данных, а не для одного пользователя. Мне просто нужно знать, как извлечь это значение и использовать его в качестве переменной в моем коде dart, используя «getString()» со ссылкой на документ или ссылкой на коллекцию, которая у меня уже есть, спасибо.

введите описание изображения здесь

 class _UserPageState extends Statelt;UserPagegt; {   User user = auth.currentUser!;  final CollectionReference collectionReference = FirebaseFirestore.instance.collection('users');    // Get profileImageUrl from users userDoc  String imageUrl = 'test'; // this should be the users imageUrl   @override  Widget build(BuildContext context) {  return Scaffold(  appBar: AppBar(  title: Text(  '${user.email}'), // this is being pulled from authentication not firestore  ),  body: Center(  child: Column(  children: [ // --------------------------- I tried using a stream builder here ---------------------  StreamBuilder(  stream: collectionReference.snapshots(),  builder: (BuildContext context,  AsyncSnapshotlt;QuerySnapshotgt; snapshot) {  if (snapshot.hasError) {  return const Text(  'Something went wrong.'); // A: use incase the data does not load  }  final data = snapshot.requireData;  return ListView.builder(  shrinkWrap: true,  itemCount: data.size,  itemBuilder: (context, index) {  return Text(  // A: Stream builder will update with all of the users email addresses, I want this for one user exclusively  'My email is ${data.docs[index]['email']}');   },  

Комментарии:

1. Вы хотите получить это изображение профиля один раз в этом методе сборки или вам нужно прослушивать удаленные изменения и автоматически обновляться при изменении базы данных?

2. Я думаю, было бы неплохо, если бы он обновлялся автоматически, но я не думаю, что мне это нужно. Я также не уверен, насколько дорого это обойдется. Я не думаю, что это так важно, но если вы знаете, как это сделать, я хотел бы попробовать

3. Если вам это нужно только один раз, используйте FutureBuilder вместо StreamBuilder , получите данные для пользователя, которые вам понадобятся в будущем, и создайте виджет соответствующим образом.

4. Если вы не хотите получать удаленные изменения, вы можете использовать StreamBuilder , как вы пытались, но запрашивать только один документ, а не все, как вы делаете в настоящее время, например collectionReference.doc(lt;document Idgt;).snapshots() , чтобы он возвращал только документ вашего пользователя.

5. Я получаю ошибку для ссылки на коллекцию при попытке переключиться с потока на будущее. Ошибка: Тип аргумента ‘Streamlt;QuerySnapshotlt;Объект?gt;lt;Объект?gt;gt;’ не может быть присвоен типу параметра ‘Futurelt;Объект?gt;gt;lt;QuerySnapshotlt;Объект?gt;lt;Объект?gt;gt;?’.

Ответ №1:

 collection('users')  .where("uid", isEqualTo: uid)  .snapshots(),  

Для фильтрации данных в коллекции firestore используйте «где». Сохраните идентификатор пользователя в автономном режиме и запросите его там, где используется сохраненный идентификатор

Комментарии:

1. Итак, теперь мой код гласит: stream: collectionReference. где(«uid», равнозначно: user.uid).моментальные снимки(), Но как мне вернуть это в качестве переменной, которую я могу отобразить за пределами моего построителя потоков?

Ответ №2:

Вы можете использовать следующую функцию для получения отдельных данных из потока.

 Streamlt;UserModelgt; getSingleStreamData({String? uId}) { return ref!.where(CommonKeys.id, isEqualTo: uId).snapshots().map((value) =gt; value.docs.first.data());}  

Комментарии:

1. Когда я верну это значение, чему оно будет присвоено за пределами потока? Я хочу использовать переменную вне потока, это та часть, в которой мне нужна помощь в присвоении значения

2. Вы можете хранить его в варибале, а затем использовать там, где захотите. или вы можете прослушать поток, чтобы там, где значение обновляется, оно прослушивало поток, и вы получали новое значение. вы можете прослушать поток в методе инициализации. например. getSingleStreamData(идентификатор пользователя).listen(данные){ }

3. Отлично! Огромное спасибо