Flutter cloud_firestore Сбой WriteBatch.commit только на iOS - PullRequest
0 голосов
/ 06 января 2020

Я пытаюсь обновить / создать несколько документов облачного хранилища с помощью 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');
    }
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...