save method
Add/Update an element of id
to collectionPath.
If linkedCollectionPath is specified, the element of linkId
is added.
The contents of data
will be added to the collectionPath/id
path.
The contents of linkedData
will be added to the linkedCollectionPath/linkId
path.
Implementation
@override
Future<void> save(
String id, {
String? linkId,
}) async {
assert(
linkId.isEmpty || (linkedCollectionPath.isNotEmpty && linkId.isNotEmpty),
"When [linkId] is specified, [linkPath] must be specified.",
);
await FirebaseCore.initialize();
// await Future.delayed(Duration(milliseconds: Random().nextInt(100)));
final firestore = FirebaseFirestore.instance;
final docPath = _counterBuilder?.call(collectionPath) ??
_buildCounterPath(collectionPath) ??
"";
final linkDocPath = linkedCollectionPath.isEmpty
? null
: (_linkedCounterBuilder?.call(linkedCollectionPath!) ??
_buildCounterPath(linkedCollectionPath!) ??
"");
await firestore.runTransaction((transaction) async {
try {
DocumentSnapshot<Map<String, dynamic>>? doc;
DocumentSnapshot<Map<String, dynamic>>? linkDoc;
await Future.wait([
transaction
.get(firestore.doc("$collectionPath/$id"))
.then((value) => doc = value),
if (!(linkId.isEmpty || linkedCollectionPath.isEmpty))
transaction
.get(firestore.doc("$linkedCollectionPath/$linkId"))
.then((value) => linkDoc = value)
]);
if (doc != null && !doc!.exists) {
transaction.set(
doc!.reference,
{
..._additionalData,
Const.uid: id,
Const.time: FieldValue.serverTimestamp(),
},
SetOptions(merge: true),
);
if (docPath.isNotEmpty) {
final key = docPath.split("/").last;
final path = docPath.replaceFirst(RegExp("/$key\$"), "");
final countDoc = <String, dynamic>{
Const.uid: path.split("/").last,
Const.time: FieldValue.serverTimestamp(),
};
countDoc.addAll(
_buildCounterUpdate(
key: key,
value: 1,
enabled: _enableCounter,
counterIntervals: _counterIntervals ?? [],
),
);
transaction.set(
firestore.doc(path),
countDoc,
SetOptions(merge: true),
);
}
}
if (linkDoc != null && !linkDoc!.exists) {
transaction.set(
linkDoc!.reference,
{
..._additionalData,
Const.uid: linkId,
Const.time: FieldValue.serverTimestamp(),
},
SetOptions(merge: true),
);
if (linkDocPath.isNotEmpty) {
final key = linkDocPath!.split("/").last;
final path = linkDocPath.replaceFirst(RegExp("/$key\$"), "");
final countDoc = <String, dynamic>{
Const.uid: path.split("/").last,
Const.time: FieldValue.serverTimestamp(),
};
countDoc.addAll(
_buildCounterUpdate(
key: key,
value: 1,
enabled: _enableCounter,
counterIntervals: _counterIntervals ?? [],
),
);
transaction.set(
firestore.doc(path),
countDoc,
SetOptions(merge: true),
);
}
}
} catch (e) {
print(e.toString());
rethrow;
}
});
}