Firebase Set transaction exception - firebase

I am getting this exception while creating a document in Firestore transaction using Flutter cloud_firestore package:
PlatformException(Error performing transaction, Every document read in a transaction must also be written., null)
This is the code:
DocumentSnapshot postSnapshot = await tx.get(post.reference);
await tx.set(Firestore.instance.collection('users').document(userId).collection('stars').
document(),docNew);
await tx.update(postSnapshot.reference, stockUpdate);
Below is the exception details:
E/flutter ( 7157): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: PlatformException(Error performing transaction, Every document read in a transaction must also be written., null)
E/flutter ( 7157): #0 StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:569:7)
E/flutter ( 7157): #1 MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:321:33)
E/flutter ( 7157): <asynchronous suspension>
E/flutter ( 7157): #2 MethodChannel.invokeMapMethod (package:flutter/src/services/platform_channel.dart:349:48)
E/flutter ( 7157): #3 MethodChannelFirestore.runTransaction (package:cloud_firestore_platform_interface/src/method_channel/method_channel_firestore.dart:123:10)
E/flutter ( 7157): #4 Firestore.runTransaction (package:cloud_firestore/src/firestore.dart:85:22)
As you see in the code, I try to create doc in one collection and update a field in another document.
Any hints to debug this? Thank you.

Related

Getting this flutter error when calling the nested list of data from firestore database. Getting null method call []("orientation")

I'm getting this null error when calling the firebase firestore database. It's working fine with my other data. Only getting error with this nested List of 'orientation'. Please help with this.
E/flutter (21191): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: NoSuchMethodError: The method '[]' was called on null.
E/flutter (21191): Receiver: null
E/flutter (21191): Tried calling: []("orientation")
E/flutter (21191): #0 Object.noSuchMethod (dart:core-patch/object_patch.dart:38:5)
E/flutter (21191): #1 new User.fromDocument (package:meetapp/models/user_model.dart:59:41)
E/flutter (21191): #2 TabbarState.getUserList.<anonymous closure>.<anonymous closure> (package:meetapp/Screens/Tab.dart:407:40)
E/flutter (21191): #3 TabbarState.getUserList.<anonymous closure>.<anonymous closure> (package:meetapp/Screens/Tab.dart:399:26)
E/flutter (21191): #4 _rootRunUnary (dart:async/zone.dart:1434:47)
E/flutter (21191): #5 _CustomZone.runUnary (dart:async/zone.dart:1335:19)
E/flutter (21191): <asynchronous suspension>
E/flutter (21191):
As you see, your doc.data() is not null, but you should also null-check ['sexualOrientation'] property. In your case, it's null, and you should write catch method for this case, because now you trying to call another property without asserting it. Let me explain.
Here is your data:
doc.data()! | is not null
↓
['sexualOrientation'] | is null so next value cant be accessed
↓
['orientation'] | cant be accessed because previous is null
What can you do:
Add assertation for second, potentionally nullable field. You can use ! or ? to check if it's null, like doc.data()!['sexualOrientation']!['orientation'] ?? []

How to access this subcollection?

I would like to know how I access this subcollection using or Futurebuilder, StreamBuilder. The first error is that it says that the document doesn't have a date, this I solve HashMapOf, but I'm not able to access UserPosts, to show on screen the documents inside UserPosts that would be posts information.
collectionReference =
firebaseFirestore.collection("posts").doc(authProv.uid).collection('userPosts');
Stream<List<PostModel>> getAllPosts() => collectionReference.snapshots().map(
(query) => query.docs.map((item) => PostModel.fromMap(item)).toList());
I'm doing like this, and on the page I'm using a ListView builder to get the length and show it on the screen, but it gives this error:
[ERROR:flutter/lib/ui/ui_dart_state.cc(199)] Unhandled Exception: Bad state: field does not exist within the DocumentSnapshotPlatform
E/flutter ( 4336): #0 DocumentSnapshotPlatform.get._findKeyValueInMap
package:cloud_firestore_platform_interface/…/platform_interface/platform_interface_document_snapshot.dart:87
E/flutter ( 4336): #1 DocumentSnapshotPlatform.get._findComponent
package:cloud_firestore_platform_interface/…/platform_interface/platform_interface_document_snapshot.dart:105
E/flutter ( 4336): #2 DocumentSnapshotPlatform.get
package:cloud_firestore_platform_interface/…/platform_interface/platform_interface_document_snapshot.dart:121
E/flutter ( 4336): #3 _JsonDocumentSnapshot.get
package:cloud_firestore/src/document_snapshot.dart:92
E/flutter ( 4336): #4 _JsonDocumentSnapshot.[]
package:cloud_firestore/src/document_snapshot.dart:96
E/flutter ( 4336): #5 new PostModel.fromMap
package:productappwithgetx/…/models/post_model.dart:25
E/flutter ( 4336): #6 PostController.getAllUsers.<anonymous closure>.<anonymous clos

Flutter: How to subscribeToTopic for Firebase (FCM) registration token in Flutter

I want to subscribeToTopic for Firebase push notification in flutter , I can subscribe to any topic but my purpose to subscribeToTopic against token , here it is the code below,
FirebaseMessaging _messaging;
Firebase.initializeApp().then((fbr) {
_messaging = FirebaseMessaging.instance;
_messaging.getToken().then((token) async{
_messaging.subscribeToTopic(token).then((value) => null);
_messaging.subscribeToTopic(userID).then((value) => null);
_messaging.subscribeToTopic(userTypeId).then((value) => null);
}
}
But I am getting error
Failed assertion: line 307 pos 10: 'isValidTopic': is not true.
log attached below:
I/flutter ( 9352): Token: dhCABsvbQ8udQJha8VOxNy:APA91bEGcpS6-QMn-c236ITNbDtxEs3MD1Q-nquedMLzZv4XWPdGUWt-Zw-OQ6YBY383IJGZXxKXNMRJd8SKLeOO7agx4dcym6VoEhPTrbYr20NoscZHTZoPCf5mqbfiTHCS5q2WlXqw
I/flutter ( 9352): User granted permission
I/flutter ( 9352): Token: dhCABsvbQ8udQJha8VOxNy:APA91bEGcpS6-QMn-c236ITNbDtxEs3MD1Q-nquedMLzZv4XWPdGUWt-Zw-OQ6YBY383IJGZXxKXNMRJd8SKLeOO7agx4dcym6VoEhPTrbYr20NoscZHTZoPCf5mqbfiTHCS5q2WlXqw
E/flutter ( 9352): [ERROR:flutter/lib/ui/ui_dart_state.cc(186)] Unhandled Exception: 'package:firebase_messaging/src/messaging.dart': Failed assertion: line 307 pos 10: 'isValidTopic': is not true.
E/flutter ( 9352): #0 _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:46:39)
E/flutter ( 9352): #1 _AssertionError._throwNew (dart:core-patch/errors_patch.dart:36:5)
E/flutter ( 9352): #2 _assertTopicName (package:firebase_messaging/src/messaging.dart:307:10)
E/flutter ( 9352): #3 FirebaseMessaging.subscribeToTopic (package:firebase_messaging/src/messaging.dart:294:5)
E/flutter ( 9352): #4 _HomePageState.registerNotification.<anonymous closure> (package:notify/main.dart:89:20)
E/flutter ( 9352): #5 _rootRunUnary (dart:async/zone.dart:1362:47)
E/flutter ( 9352): #6 _CustomZone.runUnary (dart:async/zone.dart:1265:19)
E/flutter ( 9352): #7 _FutureListener.handleValue (dart:async/future_impl.dart:152:18)
E/flutter ( 9352): #8 Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:704:45)
E/flutter ( 9352): #9 Future._propagateToListeners (dart:async/future_impl.dart:733:32)
E/flutter ( 9352): #10 Future._completeWithValue (dart:async/future_impl.dart:539:5)
E/flutter ( 9352): #11 _completeOnAsyncReturn (dart:async-patch/async_patch.dart:254:13)
E/flutter ( 9352): #12 MethodChannelFirebaseMessaging.getToken (package:firebase_messaging_platform_interface/src/method_channel/method_channel_messaging.dart)
E/flutter ( 9352): <asynchronous suspension>
The error is coming up because the token id you're passing as the topic name is not an acceptable topic name.
Here is the check that the token fails:
// https://github.com/FirebaseExtended/flutterfire/blob/master/packages/firebase_messaging/firebase_messaging/lib/src/messaging.dart
void _assertTopicName(String topic) {
bool isValidTopic = RegExp(r'^[a-zA-Z0-9-_.~%]{1,900}$').hasMatch(topic);
assert(isValidTopic);
}
Source
Use a valid string and the code should work fine.

Flutter Firestore Error performing updateData, No Document found to update

Im using Firestore for mu Flutter project.
I cannot update a field in a document. It results in error (error performing update, No document found)
Code:
await Firestore.instance.collection('QuizProfile').document("20200528-KYUMI").updateData(
{
'Slot': 'asdfg',
},
);
}
Error message ::
E/flutter (18326): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception:
PlatformException(Error performing updateData, NOT_FOUND:
No document to update: projects/fir-2d2f0/databases/(default)/documents/QuizProfile/20200528-KYUMI, null)
E/flutter (18326): #0 StandardMethodCodec.decodeEnvelope
package:flutter/…/services/message_codecs.dart:569
E/flutter (18326): #1 MethodChannel.invokeMethod
package:flutter/…/services/platform_channel.dart:321
E/flutter (18326): <asynchronous suspension>
E/flutter (18326): #2 MethodChannelDocumentReference.updateData
package:cloud_firestore_platform_interface/…/method_channel/method_channel_document_reference.dart:41
E/flutter (18326): #3 DocumentReference.updateData
package:cloud_firestore/src/document_reference.dart:60
E/flutter (18326): #4 Model.pushscore
package:firestoredemo/models/QA_Model.dart:214
E/flutter (18326): <asynchronous suspension>
E/flutter (18326): #5 _CustomTextState.initState
package:firestoredemo/CustomText.dart:21
Firestore database screenshot

Firestore access broken after an offline attempt

I'm trying to access to a Cloud Firestore with this piece of code :
void _submit(BuildContext context) async {
final DocumentReference postRef = Firestore.instance.document(dbPath);
Firestore.instance.runTransaction((transaction) async {
DocumentSnapshot freshSnap = await transaction.get(postRef);
await transaction.update(freshSnap.reference, {
'value': freshSnap['value'] + 1
});
});
}
If wifi or mobile data are on, everything works fine. (as expected)
If wifi and mobile data are off, it does not work. (as expected). But when I wait until the timeout (after calling the method) and only then, turn mobile data and wifi on, it does not work anymore and I get the following errors :
E/flutter ( 7041): [ERROR:topaz/lib/tonic/logging/dart_error.cc(16)] Unhandled exception:
E/flutter ( 7041): PlatformException(Error performing transaction, Timed out waiting for Task, null)
E/flutter ( 7041): #0 StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:547:7)
E/flutter ( 7041): #1 MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:279:18)
E/flutter ( 7041): <asynchronous suspension>
E/flutter ( 7041): #2 Firestore.runTransaction (file:///C:/{myPath}/flutter/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.7.3/lib/src/firestore.dart:115:10)
E/flutter ( 7041): <asynchronous suspension>
E/flutter ( 7041): #3 _FeedbackPageState._submitFeedback (package:appli_salon_data/view/program/FeedbackPage.dart:74:26)
E/flutter ( 7041): <asynchronous suspension>
E/flutter ( 7041): #4 _FeedbackPageState.build.<anonymous closure> (package:appli_salon_data/view/program/FeedbackPage.dart:60:26)
E/flutter ( 7041): #5 _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:494:14)
E/flutter ( 7041): #6 _InkResponseState.build.<anonymous closure> (package:flutter/src/material/ink_well.dart:549:30)
E/flutter ( 7041): #7 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:102:24)
E/flutter ( 7041): #8 TapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:161:9)
E/flutter ( 7041): #9 TapGestureRecognizer.acceptGesture (package:flutter/src/gestures/tap.dart:123:7)
E/flutter ( 7041): #10 GestureArenaManager.sweep (package:flutter/src/gestures/arena.dart:156:27)
E/flutter ( 7041): #11 _WidgetsFlutterBinding&BindingBase&GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:147:20)
E/flutter ( 7041): #12 _WidgetsFlutterBinding&BindingBase&GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:121:22)
E/flutter ( 7041): #13 _WidgetsFlutterBinding&BindingBase&GestureBinding._handlePointerEvent (package:flutter/src/gestures/binding.dart:101:7)
E/flutter ( 7041): #14 _WidgetsFlutterBinding&BindingBase&GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:64:7)
E/flutter ( 7041): #15 _WidgetsFlutterBinding&BindingBase&GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:48:7)
E/flutter ( 7041): #16 _invoke1 (dart:ui/hooks.dart:134:13)
E/flutter ( 7041): #17 _dispatchPointerDataPacket (dart:ui/hooks.dart:91:5)
(not expected)
The method won't work again until I relaunch the app.
If anyone has some explanation about this behaviour, feel free to answer :)
UPDATE : I tried this :
Switch off Wifi
Try to run the transaction - results in expected failure
Switch on Wifi
Try to run the transaction
Here is the interesting part : at step 4, the transaction is "immediately" run twice, both times getting the error :
PlatformException(Error performing Transaction#get, UNAVAILABLE: Unable to resolve host firestore.googleapis.com, null)
when calling transaction.get(postRef).
Could it mean that Firestore somehow loses all access to the host after losing Internet connection briefly once ? How can I fix that ?
Have you tried enabling local persistence? Not sure if that'll catch the issue, but it might be worth a try. I believe this is done using the persistenceEnabled parameter in the settings method:
Firestore.instance.settings(persistenceEnabled: true)
Keep in mind that this should only be done once, so it should go somewhere in your code that won't get called every time you access any Firestore data.

Resources