save method

  1. @override
Future<void> save(
  1. String id, {
  2. String? linkId,
})
override

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;
    }
  });
}