createDoc method
Future<TurboResponse<DocumentReference<Object?> > >
createDoc({
- required TurboWriteable writeable,
- String? id,
- WriteBatch? writeBatch,
- TurboTimestampType createTimeStampType = TurboTimestampType.createdAtAndUpdatedAt,
- TurboTimestampType updateTimeStampType = TurboTimestampType.updatedAt,
- bool merge = false,
- List<
FieldPath> ? mergeFields, - String? collectionPathOverride,
- Transaction? transaction,
Creates or writes a document to Firestore.
This method provides a flexible way to create or update documents with various options for handling timestamps, batching, transactions, and merging.
Parameters:
writeable
The data to write, must implement TurboWriteableid
Optional custom document ID (auto-generated if not provided)writeBatch
Optional batch to include this operation increateTimeStampType
Type of timestamp to add for new documentsupdateTimeStampType
Type of timestamp to add when mergingmerge
Whether to merge with existing documentmergeFields
Specific fields to merge (ifmerge
is true)collectionPathOverride
Optional different collection pathtransaction
Optional transaction to include this operation in
Returns a TurboResponse
containing either:
- Success with the
DocumentReference
of the created document - Failure with validation errors or operation errors
Features:
- Automatic validation through TurboWriteable.validate
- Timestamp management based on operation type
- Support for batch operations
- Support for transactions
- Merge/upsert capabilities
Example:
final user = User(name: 'John');
final response = await api.createDoc(
writeable: user,
id: 'user-123',
merge: true,
);
response.when(
success: (ref) => print('Created user: ${ref.id}'),
fail: (error) => print('Error: $error'),
);
See also:
- createDocInBatch for batch operations
- TurboTimestampType for timestamp options
Implementation
Future<TurboResponse<DocumentReference>> createDoc({
required TurboWriteable writeable,
String? id,
WriteBatch? writeBatch,
TurboTimestampType createTimeStampType =
TurboTimestampType.createdAtAndUpdatedAt,
TurboTimestampType updateTimeStampType = TurboTimestampType.updatedAt,
bool merge = false,
List<FieldPath>? mergeFields,
String? collectionPathOverride,
Transaction? transaction,
}) async {
assert(
_isCollectionGroup == (collectionPathOverride != null),
'Firestore does not support finding a document by id when communicating with a collection group, '
'therefore, you must specify the collectionPathOverride containing all parent collection and document ids '
'in order to make this method work.',
);
try {
_log.debug(
message: 'Checking if writeable is valid..', sensitiveData: null);
final TurboResponse<DocumentReference>? invalidResponse =
writeable.validate();
if (invalidResponse != null && invalidResponse.isFail) {
_log.warning(
message: 'TurboWriteable was invalid!',
sensitiveData: null,
);
return invalidResponse;
}
_log.info(message: 'TurboWriteable is valid!', sensitiveData: null);
_log.debug(
message: 'Creating document..',
sensitiveData: SensitiveData(
path: collectionPathOverride ?? _collectionPath(),
id: id,
isBatch: writeBatch != null,
createTimeStampType: createTimeStampType,
updateTimeStampType: updateTimeStampType,
isMerge: merge,
mergeFields: mergeFields,
isTransaction: transaction != null,
),
);
if (writeBatch != null) {
_log.debug(
message: 'WriteBatch was not null! Creating with batch..',
sensitiveData: null);
final lastBatchResponse = await createDocInBatch(
writeable: writeable,
id: id,
writeBatch: writeBatch,
createTimeStampType: createTimeStampType,
updateTimeStampType: updateTimeStampType,
collectionPathOverride: collectionPathOverride,
merge: merge,
mergeFields: mergeFields,
);
_log.debug(
message: 'Checking if batchCreate was successful..',
sensitiveData: null);
return _handleBatchOperation(lastBatchResponse);
} else {
_log.debug(
message: 'WriteBatch was null! Creating without batch..',
sensitiveData: null);
final documentReference = id != null
? getDocRefById(
id: id,
collectionPathOverride: collectionPathOverride,
)
: _firebaseFirestore
.collection(collectionPathOverride ?? _collectionPath())
.doc();
_log.debug(
message: 'Creating JSON..',
sensitiveData: null,
);
final writeableAsJson = (merge || mergeFields != null) &&
(await documentReference.get(_getOptions)).exists
? updateTimeStampType.add(
writeable.toJson(),
updatedAtFieldName: _updatedAtFieldName,
createdAtFieldName: _createdAtFieldName,
)
: createTimeStampType.add(
writeable.toJson(),
createdAtFieldName: _createdAtFieldName,
updatedAtFieldName: _updatedAtFieldName,
);
var setOptions = SetOptions(
merge: mergeFields == null ? merge : null,
mergeFields: mergeFields,
);
if (transaction == null) {
_log.debug(
message: 'Setting data with documentReference.set..',
sensitiveData: SensitiveData(
path: collectionPathOverride ?? _collectionPath(),
id: documentReference.id,
data: writeableAsJson,
),
);
await documentReference.set(
writeableAsJson,
setOptions,
);
} else {
_log.debug(
message: 'Setting data with transaction.set..',
sensitiveData: SensitiveData(
path: collectionPathOverride ?? _collectionPath(),
id: documentReference.id,
data: writeableAsJson,
),
);
transaction.set(
getDocRefById(id: documentReference.id),
writeableAsJson,
setOptions,
);
}
_log.info(
message: 'Setting data done!',
sensitiveData: null,
);
return TurboResponse.success(result: documentReference);
}
} catch (error, stackTrace) {
if (transaction != null) {
// Wrap and rethrow for transactions
throw TurboFirestoreException.fromFirestoreException(
error,
stackTrace,
path: collectionPathOverride ?? _collectionPath(),
query: 'createDoc(id: $id, merge: $merge)',
);
}
_log.error(
message: 'Unable to create document',
sensitiveData: SensitiveData(
path: collectionPathOverride ?? _collectionPath(),
id: id,
isBatch: writeBatch != null,
createTimeStampType: createTimeStampType,
updateTimeStampType: updateTimeStampType,
isMerge: merge,
mergeFields: mergeFields,
isTransaction: false,
),
error: error,
stackTrace: stackTrace,
);
// Convert to TurboFirestoreException and wrap in TurboResponse
final exception = TurboFirestoreException.fromFirestoreException(
error,
stackTrace,
path: collectionPathOverride ?? _collectionPath(),
query: 'createDoc(id: $id, merge: $merge)',
);
return TurboResponse.fail(error: exception);
}
}