Я пытаюсь обновить / создать несколько документов облачного хранилища с помощью WriteBatch. Это работает нормально на Android, однако, кажется, что это невозможно по iOS из-за этой ошибки:
2020-01-05 21:31:54.767517-0800 Runner[514:143367] -[NSNull length]: unrecognized selector sent to instance 0x1f12ab9a0
2020-01-05 21:31:54.772421-0800 Runner[514:143367] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSNull length]: unrecognized selector sent to instance 0x1f12ab9a0'
Нет случаев вызова длина в методе, который терпит неудачу (код ниже), и я не смог найти никаких других подсказок, почему он терпит неудачу. Код выполняется до команды batch.commit()
, а затем завершается ошибкой (и не фиксирует какие-либо записи в базу данных). Я отчаянно нуждаюсь в помощи, огромное спасибо всем, кто посмотрел!
Future<void> sendDirectPost(String messageTitle, String audioPath, int secondsLength, {String conversationId, Map<String, dynamic> memberMap, String fileUrl}) async {
String _conversationId = conversationId;
if(isLoggedIn()) {
WriteBatch batch = Firestore.instance.batch();
DateTime date = DateTime.now();
//Create document for new direct post message
DocumentReference directPostRef = Firestore.instance.collection('/directposts').document();
String directPostDocId = directPostRef.documentID;
//Get posting user id and username
DocumentReference postingUserDoc = await UserManagement().getUserData();
String postingUserID = postingUserDoc.documentID;
String postingUsername = await postingUserDoc.get().then((DocumentSnapshot snapshot) async {
return snapshot.data['username'].toString();
});
//Upload audio file
String fileUrlString;
if(fileUrl == null) {
//Get audio file
File audioFile = File(audioPath);
String dateString = DateFormat("yyyy-MM-dd_HH_mm_ss").format(date).toString();
final StorageReference storageRef = FirebaseStorage.instance.ref().child(postingUserID).child('direct-posts').child(dateString);
final StorageUploadTask uploadTask = storageRef.putFile(audioFile);
String _fileUrl = await (await uploadTask.onComplete).ref.getDownloadURL();
fileUrlString = _fileUrl.toString();
} else {
fileUrlString = fileUrl.toString();
}
//Check if conversation exists
List<String> _memberList = new List<String>();
if(memberMap != null)
_memberList.addAll(memberMap.keys);
_memberList.sort();
if(_conversationId == null){
await Firestore.instance.collection('conversations').where('memberList', isEqualTo: _memberList).getDocuments().then((snapshot) {
if(snapshot.documents.isNotEmpty) {
DocumentSnapshot conversation = snapshot.documents.first;
if(conversation != null)
_conversationId = conversation.reference.documentID;
}
});
}
bool conversationExists = _conversationId != null;
Map<String, dynamic> conversationMap = await postingUserDoc.get().then((DocumentSnapshot snapshot) {
return snapshot.data['directConversationMap'] == null ? null : Map<String, dynamic>.from(snapshot.data['directConversationMap']);
});
if(conversationExists) {
print('Conversation exists: $_conversationId');
DocumentReference conversationRef = Firestore.instance.collection('/conversations').document(_conversationId);
Map<String, dynamic> postMap;
Map<String, dynamic> conversationMembers;
await conversationRef.get().then((DocumentSnapshot snapshot) {
postMap = Map<String, dynamic>.from(snapshot.data['postMap']);
conversationMembers = Map<String, dynamic>.from(snapshot.data['conversationMembers']);
});
//increment unread posts for all users other than posting user
print('Members: $conversationMembers');
Map<String, dynamic> newMemberMap = new Map<String, dynamic>();
conversationMembers.forEach((uid, details) {
Map<dynamic, dynamic> newDetails = details;
if(uid != postingUserID) {
int unheardCnt = details['unreadPosts'];
if(unheardCnt != null)
unheardCnt = unheardCnt + 1;
newDetails['unreadPosts'] = unheardCnt;
}
newMemberMap[uid] = newDetails;
});
postMap.addAll({directPostDocId: postingUserID});
batch.updateData(conversationRef, {'postMap': postMap, 'lastDate': date, 'conversationMembers': newMemberMap});
} else {
//Create new conversation document and update data
DocumentReference newConversationRef = Firestore.instance.collection('/conversations').document();
conversationId = newConversationRef.documentID;
print('creating new conversation: $conversationId');
Map<String, dynamic> conversationMembers = new Map<String, dynamic>();
memberMap.forEach((uid, username) {
if(uid == postingUserID)
conversationMembers.addAll({uid: {'username': username, 'unreadPosts': 0}});
else
conversationMembers.addAll({uid: {'username': username, 'unreadPosts': 1}});
});
Map<String, dynamic> postMap = {directPostDocId: postingUserID};
batch.setData(newConversationRef, {'conversationMembers': conversationMembers, 'postMap': postMap, 'memberList': _memberList, 'lastDate': date});
//Add a new conversation to the sending user doc conversationMap
Map<String, dynamic> senderConversationMap = await postingUserDoc.get().then((DocumentSnapshot snapshot) {
return snapshot.data['directConversationMap'] == null ? null : Map<String, dynamic>.from(snapshot.data['directConversationMap']);
});
Map<String, dynamic> sendConvoData = {_conversationId: true};
if(senderConversationMap != null)
senderConversationMap.addAll(sendConvoData);
else
senderConversationMap = sendConvoData;
batch.updateData(postingUserDoc, {'directConversationMap': senderConversationMap});
}
//Add data to new direct post document (message title, file url, length, date, sender, recipient, conversationId)
Map<String, dynamic> newPostData = {'senderUID': postingUserID, 'senderUsername': postingUsername, 'messageTitle': messageTitle,
'secondsLength': secondsLength, 'audioFileLocation': fileUrlString, 'conversationId': _conversationId != null ? _conversationId : conversationId,
'datePosted': date
};
batch.setData(directPostRef, newPostData);
print('commiting batch');
await batch.commit().catchError(((error) {
print('Error committing batch: $error');
}));
print('batch committed');
}
}