sakibguy / worked-issues

arget medi a[rpescriptionmedicie] &ssets[dr] (reeeverse._ax:p)
2 stars 0 forks source link

[ORG] SG-MYALICE: Button gallery block exception by pusher on UI #115

Closed sakibguy closed 1 year ago

sakibguy commented 1 year ago

PROB

Button Gallery: get-conversation (showing button gallery) but pusher/realtime getting exception.

SNaP

Screenshot (639)

EXCEP

exception 1

======== Exception caught by widgets library =======================================================
The following _CastError was thrown building ConversationBaseWidget(dirty, state: _ConversationBaseWidget#753bc):
Null check operator used on a null value

The relevant error-causing widget was: 
  ConversationBaseWidget ConversationBaseWidget:file:///D:/myalice_app/lib/screens/chatDetails/chatDetails.dart:371:43
When the exception was thrown, this was the stack: 
#0      _ConversationBaseWidget.getBorderBarHeight (package:myalice/screens/chatDetails/customWidgets/conversationWidgets/conversationBaseWidget.dart:195:45)
#1      _ConversationBaseWidget.build (package:myalice/screens/chatDetails/customWidgets/conversationWidgets/conversationBaseWidget.dart:437:53)
#2      StatefulElement.build (package:flutter/src/widgets/framework.dart:4992:27)
#3      ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4878:15)
#4      StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5050:11)
#5      Element.rebuild (package:flutter/src/widgets/framework.dart:4604:5)
#6      ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:4859:5)
#7      StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:5041:11)
#8      ComponentElement.mount (package:flutter/src/widgets/framework.dart:4853:5)
#9      Element.inflateWidget (package:flutter/src/widgets/framework.dart:3863:16)
#10     MultiChildRenderObjectElement.inflateWidget (package:flutter/src/widgets/framework.dart:6435:36)
#11     MultiChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:6447:32)
...     Normal element mounting (41 frames)
#52     Element.inflateWidget (package:flutter/src/widgets/framework.dart:3863:16)
#53     Element.updateChild (package:flutter/src/widgets/framework.dart:3586:20)
#54     SliverMultiBoxAdaptorElement.updateChild (package:flutter/src/widgets/sliver.dart:1405:37)
#55     SliverMultiBoxAdaptorElement.performRebuild.processElement (package:flutter/src/widgets/sliver.dart:1306:35)
#56     Iterable.forEach (dart:core/iterable.dart:325:35)
#57     SliverMultiBoxAdaptorElement.performRebuild (package:flutter/src/widgets/sliver.dart:1353:24)
#58     SliverMultiBoxAdaptorElement.update (package:flutter/src/widgets/sliver.dart:1282:7)
#59     Element.updateChild (package:flutter/src/widgets/framework.dart:3570:15)

exception 2

======== Exception caught by scheduler library =====================================================
The following assertion was thrown during a scheduler callback:
ScrollController not attached to any scroll views.
'package:flutter/src/widgets/scroll_controller.dart':
Failed assertion: line 107 pos 12: '_positions.isNotEmpty'

When the exception was thrown, this was the stack: 
#2      ScrollController.position (package:flutter/src/widgets/scroll_controller.dart:107:12)
#3      _ConvBtnQuickReplyWidget.initState.<anonymous closure> (package:myalice/screens/chatDetails/customWidgets/conversationWidgets/conversationBtnQuickReplyWidget.dart:48:52)
#4      SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1175:15)
#5      SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1113:9)
#6      SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:1015:5)
#7      _invoke (dart:ui/hooks.dart:148:13)
#8      PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:318:5)
#9      _drawFrame (dart:ui/hooks.dart:115:31)
(elided 2 frames from class _AssertionError)
====================================================================================================
sakibguy commented 1 year ago

Pusher resp

{"type": "message", "source": "bot", "platform_type": "facebook_messenger", "platform_id": 1361, "customer_id": 1043, "project_id": 375, "conversation_id": "m_45EF2QmBrO4_krkp30HFOk6MoMJwaz_uVqGmpI3rBU9zznxcJN5lbyn1MaJzZAbiOY5rcKItdTHTgaDm9j6p9w", "success": true, "report": {"recipient_id": "4533558773428509", "message_id": "m_45EF2QmBrO4_krkp30HFOk6MoMJwaz_uVqGmpI3rBU9zznxcJN5lbyn1MaJzZAbiOY5rcKItdTHTgaDm9j6p9w"}, "timestamp": 1671446031085, "data": {"type": "quick_reply", "data": {"text": "Take a tour on our site..", "title": null, "save": false, "attribute": null, "buttons": [{"id": 1, "type": "sequence", "extra": "", "title": "Button Gallery", "value": 5500, "payload": "SEQ5500-1644133268903", "verbose": "imu - Gallery", "input_value": ""}, {"id": 2, "type": "sequence", "extra": "", "title": "Button Image", "value": 7723, "payload": "SEQ7723-1670503776191", "verbose": "image block", "input_value": ""}, {"id": 3, "type": "sequence", "extra": "", "title": "Button", "value": 7724, "payload": "SEQ7724-1670503828924", "verbose": "button block", "input_value": ""}], "api": null}}, "dataV2": {}}

SNaP

Screenshot (641)

sakibguy commented 1 year ago

SOLn

Update data model by ElementButton as pusher resp

class ElementButtons {
  int? id;
  String? type;
  String? extra;
  String? title;
  String? value;
  String? payload;
  String? verbose;
  int? formSequence;
  //Null formSequenceTitle;
  bool? messengerExtensions;
  String? webviewHeightRatio;

  ElementButtons(
      {this.id,
        this.type,
        this.extra,
        this.title,
        this.value,
        this.payload,
        this.verbose,
        this.formSequence,
        // this.formSequenceTitle,
        this.messengerExtensions,
        this.webviewHeightRatio});

  ElementButtons.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    type = json['type'];
    extra = json['extra'];
    title = json['title'];
    value = json['value'].toString();
    payload = json['payload'];
    verbose = json['verbose'];
    formSequence = json['form_sequence'];
    // formSequenceTitle = json['form_sequence_title'];
    messengerExtensions = json['messenger_extensions'];
    webviewHeightRatio = json['webview_height_ratio'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['id'] = this.id;
    data['type'] = this.type;
    data['extra'] = this.extra;
    data['title'] = this.title;
    data['value'] = this.value;
    data['payload'] = this.payload;
    data['verbose'] = this.verbose;
    data['form_sequence'] = this.formSequence;
    // data['form_sequence_title'] = this.formSequenceTitle;
    data['messenger_extensions'] = this.messengerExtensions;
    data['webview_height_ratio'] = this.webviewHeightRatio;
    return data;
  }
}
sakibguy commented 1 year ago

EXCEP

Model updated successfully but getting same excep Scroll & not null operator exception https://github.com/sakibguy/worked-issues/issues/115#issue-1502691649

SNaP

Screenshot (643)

sakibguy commented 1 year ago

REASON

REALTIME COMPATIBALITY/PARSING ISSUE (DATA vs DATAV2)

SNaP

1

Code snippets

Bot button response

D/PusherClientPlugin( 6299): [ON_EVENT] Channel: chat-C_1043, EventName: messages,
D/PusherClientPlugin( 6299): Data: {"type": "message", "source": "bot", "platform_type": "facebook_messenger", "platform_id": 1361, "customer_id": 1043, "project_id": 375, "conversation_id": "m_QSB59_GuO7OuE_c6Ovodnk6MoMJwaz_uVqGmpI3rBU_TePXvPQa4n5xm4zaWikKuCKjf1WgnXd5NHmi8mnwa4A", "success": true, "report": {"recipient_id": "4533558773428509", "message_id": "m_QSB59_GuO7OuE_c6Ovodnk6MoMJwaz_uVqGmpI3rBU_TePXvPQa4n5xm4zaWikKuCKjf1WgnXd5NHmi8mnwa4A"}, "timestamp": 1671462793953, "data": {"type": "quick_reply", "data": {"text": "Quick Reply block test Quick Reply block test Quick Reply block test Quick Reply block test Quick Reply block test Quick Reply block test Quick Reply block test Quick Reply block test Quick Reply block test Quick Reply block test", "title": null, "save": false, "attribute": null, "buttons": [{"id": 1, "type": "sequence", "extra": "", "title": "Button Title", "value": 7723, "payload": "SEQ7723-1670503776191", "verbose": "image block", "input_value": ""}, {"id": 2, "type": "sequence", "extra": "", "title": "Button Title", "value": 7723, "payload": "SEQ7723-1670503776191", "verbose": "image block", "input_value": ""}], "api": null}}, "dataV2": {}}

Pusher bot

if (doAdd) {
            var chatDataSource = ChatDataSource(
                sId: text['_id'],
                text: text['data']['data']['text'],
                source: text['source'],
                timestamp: text['timestamp'],
                type: text['data']['type'],
                subType: text['data']['type'] == "attachment"
                    ? text['data']['data']["sub_type"]
                    : "",
                pusherKey: text['pusher_key'],
                platformId: text['platform_id'],
                platformType: text['platform_type'],
                customerId: text['customer_id'],
                report: text['report'] != null
                    ? Report.fromJson(text['report'])
                    : null,
                adminId: text['admin_id'],
                adminInfo: text['admin_info'] != null
                    ? AdminInfo.fromJson(text['admin_info'])
                    : null,
                conversationId: text['conversation_id'],
                imageUrls: text['data']['type'] == "attachment"
                    ? text['data']['data']["sub_type"] == "image"
                    ? text['data']["data"]["urls"].cast<String>()
                    : []
                    : [],
                attachedUrl: text['data']['type'] == "attachment"
                    ? text['data']['data']["sub_type"] == "file"
                    ? text['data']["data"]["urls"].cast<String>()
                    : []
                    : [],
                videoUrls: text['data']['type'] == "attachment"
                    ? text['data']['data']["sub_type"] == "video"
                    ? text['data']["data"]["urls"].cast<String>()
                    : []
                    : [],
                imageUrl: text['data']['type'] == "attachment"
                    ? text['data']['data']["sub_type"] == "image"
                    ? text['data']["data"]["urls"][0]
                    : ""
                    : "",
                audioUrl: text['data']['type'] == "attachment"
                    ? text['data']['data']["sub_type"] == "audio"
                    ? text['data']["data"]["urls"].cast<String>()
                    : []
                    : [],
                data: text['data'] != null
                    ? new Data.fromJson(text['data'])
                    : null);
            print('[---ok---] pusher_bot: ${chatDataSource.toJson()}');

            if (text['source'] == "bot" || chatDataSource.type == "template") {
              chatDataSource.isPusherSucceeded.value = true;
            }
            Get.find<ChatApiController>().addToChatList(chatDataSource);
          }
        }
      });

prints all null

print('[---ok---] pusher_bot: ${chatDataSource.toJson()}');

I/flutter ( 6299): [---ok---] pusher_bot: {id: null, source: bot, type: quick_reply, platform_type: facebook_messenger, event: null, conversation_id: m_QSB59_GuO7OuE_c6Ovodnk6MoMJwaz_uVqGmpI3rBU_TePXvPQa4n5xm4zaWikKuCKjf1WgnXd5NHmi8mnwa4A, timestamp: 1671462793953, platform_id: 1361, project_id: null, customer_id: 1043, is_seen: null, is_delivered: null, dataV2: {type: quick_reply, success: null, error: null, text: null, payload: null, sub_type: null, urls: null}, success: null, report: {recipient_id: 4533558773428509, message_id: m_QSB59_GuO7OuE_c6Ovodnk6MoMJwaz_uVqGmpI3rBU_TePXvPQa4n5xm4zaWikKuCKjf1WgnXd5NHmi8mnwa4A}, admin_id: null, pusher_key: null}
I/flutter ( 6299): event data:true {id: null, source: bot, type: quick_reply, platform_type: facebook_messenger, event: null, conversation_id: m_QSB59_GuO7OuE_c6Ovodnk6MoMJwaz_uVqGmpI3rBU_TePXvPQa4n5xm4zaWikKuCKjf1WgnXd5NHmi8mnwa4A, timestamp: 1671462793953, platform_id: 1361, project_id: null, customer_id: 1043, is_seen: null, is_delivered: null, dataV2: {type: quick_reply, success: null, error: null, text: null, payload: null, sub_type: null, urls: null}, success: null, report: {recipient_id: 4533558773428509, message_id: m_QSB59_GuO7OuE_c6Ovodnk6MoMJwaz_uVqGmpI3rBU_TePXvPQa4n5xm4zaWikKuCKjf1WgnXd5NHmi8mnwa4A}, admin_id: null, pusher_key: null}

Chat List Model

class ChatDataSource {
  String? sId;
  String? source;
  String? type;
  String? event;
  String? platformType;
  //int? conversationId;
  int? timestamp;
  int? platformId;
  int? projectId;
  int? customerId;
  bool? isSeen;
  bool? isDelivered;
  bool? success;

  Data? data;
  Report? report;
  int? adminId;
  AdminInfo? adminInfo;

  String? pusherKey;
  List<String>? imageUrls;
  List<String>? videoUrls;
  List<String>? attachedUrl;
  List<String>? audioUrl;
  RxBool isPusherSucceeded = false.obs;

  //For DB
  String? text;
  String? imageUrl;
  String? subType;
  dynamic? conversationId;

  ChatDataSource(
      {this.sId,
      this.text,
      this.source,
      this.timestamp,
      this.type,
      this.subType,
      this.platformId,
      this.platformType,
      this.customerId,
      this.report,
      this.adminId,
      this.adminInfo,
      this.conversationId,
      this.imageUrls,
      this.videoUrls,
      this.imageUrl,
      this.audioUrl,
      this.attachedUrl,
      this.data,
      this.event,
      this.projectId,
      this.isSeen,
      this.isDelivered,
      this.success,
      this.pusherKey,
      });

  ChatDataSource.fromJson(Map<String, dynamic> json) {
    sId = json[JKChatResponse.ID];
    source = json[JKChatResponse.SOURCE];
    type = json[JKChatResponse.TYPE];
    platformType = json[JKChatResponse.PLATFORM_TYPE];
    event = json[JKChatResponse.EVENT];
    conversationId = json[JKChatResponse.CONVERSATION_ID];
    timestamp = json[JKChatResponse.TIMESTAMP];
    platformId = json[JKChatResponse.PLATFORM_ID];
    projectId = json[JKChatResponse.PROJECT_ID];
    customerId = json[JKChatResponse.CUSTOMER_ID];
    isSeen = json[JKChatResponse.IS_SEEN];
    isDelivered = json[JKChatResponse.IS_DELIVERED];
    data = json[JKChatResponse.DATA] != null ? new Data.fromJson(json[JKChatResponse.DATA]) : null;
    success = json[JKChatResponse.SUCCESS];
    report =
        json[JKChatResponse.REPORT] != null ? new Report.fromJson(json[JKChatResponse.REPORT]) : null;
    adminId = json[JKChatResponse.ADMIN_ID];
    adminInfo = json[JKChatResponse.ADMIN_INFO] != null
        ? new AdminInfo.fromJson(json[JKChatResponse.ADMIN_INFO])
        : null;
    this.text = json[JKChatResponse.TEXT];
    this.subType = json[JKChatResponse.SUB_TYPE];
    this.pusherKey = json[JKChatResponse.PUSHER_KEY];

    // this.imageUrls = json[JKChatResponse.DATA].json[JKChatResponse.URLS];
    // this.videoUrls = json[JKChatResponse.DATA].json[JKChatResponse.URLS];
    this.text = json[JKChatResponse.TEXT];
    this.imageUrl = json['image_url'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data[JKChatResponse.ID] = this.sId;
    data[JKChatResponse.SOURCE] = this.source;
    data[JKChatResponse.TYPE] = this.type;
    data[JKChatResponse.PLATFORM_TYPE] = this.platformType;
    data[JKChatResponse.EVENT] = this.event;
    data[JKChatResponse.CONVERSATION_ID] = this.conversationId;
    data[JKChatResponse.TIMESTAMP] = this.timestamp;
    data[JKChatResponse.PLATFORM_ID] = this.platformId;
    data[JKChatResponse.PROJECT_ID] = this.projectId;
    data[JKChatResponse.CUSTOMER_ID] = this.customerId;
    data[JKChatResponse.IS_SEEN] = this.isSeen;
    data[JKChatResponse.IS_DELIVERED] = this.isDelivered;
    if (this.data != null) {
      data[JKChatResponse.DATA] = this.data!.toJson();
    }
    data[JKChatResponse.SUCCESS] = this.success;
    if (this.report != null) {
      data[JKChatResponse.REPORT] = this.report!.toJson();
    }
    data[JKChatResponse.ADMIN_ID] = this.adminId;
    data[JKChatResponse.PUSHER_KEY] = this.pusherKey;
    if (this.adminInfo != null) {
      data[JKChatResponse.ADMIN_INFO] = this.adminInfo!.toJson();
    }
    return data;
  }

  Map<String, dynamic> toJsonForDB() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data[JKChatResponse.TEXT] =
        this.source == JKChatResponse.CUSTOMER ? this.data!.text : this.data!.text;
    data[JKChatResponse.URLS] = this.source == JKChatResponse.CUSTOMER
        ? this.data!.type == JKChatResponse.ATTACHMENT
            ? this.data!.subType == JKChatResponse.IMAGE
                ? this.data!.urls!.elementAt(0)
                : ""
            : ""
        : this.data!.type == JKChatResponse.ATTACHMENT
            ? this.data!.subType == JKChatResponse.IMAGE
                ? this.data!.urls!.elementAt(0)
                : ""
            : "";
    data[JKChatResponse.URLS] = this.source == JKChatResponse.CUSTOMER
        ? this.data!.type == JKChatResponse.ATTACHMENT
            ? this.data!.subType == JKChatResponse.IMAGE
                ? this.data!.urls!
                : []
            : []
        : this.data!.type == JKChatResponse.ATTACHMENT
            ? this.data!.subType == JKChatResponse.IMAGE
                ? this.data!.urls!
                : []
            : [];
    data[JKChatResponse.URLS] = this.source == JKChatResponse.CUSTOMER
        ? this.data!.type == JKChatResponse.ATTACHMENT
            ? this.data!.subType == JKChatResponse.VIDEO
                ? this.data!.urls!
                : []
            : []
        : this.data!.type == JKChatResponse.ATTACHMENT
            ? this.data!.subType == JKChatResponse.VIDEO
                ? this.data!.urls!
                : []
            : [];
    data[JKChatResponse.URLS] = this.source == JKChatResponse.CUSTOMER
        ? this.data!.type == JKChatResponse.ATTACHMENT
          ? this.data!.subType == JKChatResponse.FILE
            ? this.data!.urls!
            : []
          : []
        : this.data!.type == JKChatResponse.ATTACHMENT
          ? this.data!.subType == JKChatResponse.FILE
            ? this.data!.urls!
              : []
          : [];
    data[JKChatResponse.SOURCE] = this.source;
    data[JKChatResponse.TYPE] = this.data!.type;
    data[JKChatResponse.SUB_TYPE] = this.source == JKChatResponse.ADMIN || this.source == JKChatResponse.BOT
        ? (this.data!.type == JKChatResponse.ATTACHMENT ? this.data!.subType : "")
        : (this.data!.type == JKChatResponse.ATTACHMENT ? this.data!.type : "");
    data[JKChatResponse.TIMESTAMP] = this.timestamp;
    return data;
  }

  @override
  String toString() {
    return 'Chats {text : ${this.source == JKChatResponse.CUSTOMER ? this.data!.text : this.data?.text}}';
  }
}
sakibguy commented 1 year ago

data to dataV2 Parsed

Log: pusher_bot:

{type: null, success: null, error: null, text: Button block test Button block test Button block test Button block test Button block test Button block test Button block test Button block test Button block test, payload: null, sub_type: null, urls: null, buttons: [{id: 1, type: sequence, extra: , title: Button Title 1, value: 7723, payload: SEQ7723-1670503776191, verbose: image block}, {id: 2, type: sequence, extra: , title: Button Title 2, value: 7723, payload: SEQ7723-1670503776191, verbose: image block}, {id: 3, type: sequence, extra: , title: Button Title 3, value: 7723, payload: SEQ7723-1670503776191, verbose: image block}]}

SNaP

Screenshot (645)

sakibguy commented 1 year ago

data vs dataV2 not compatible

if make compatible complexity be raised on UI + pusher for chatlist updates be required extra codes. Not impossible! But not good practices!

USHER: data(raise complexity) or dataV2(bot resp not ready)

Screenshot (646)

Screenshot (647)

Screenshot (648)

sakibguy commented 1 year ago

SOLn

Nargis Apu, got a solution and I would know from new changes https://github.com/sakibguy/worked-issues/issues/108#issuecomment-1366468998

So, closed the issue.