Flutter Map <string,dynamic =“”>错误

时间:2018-05-03 16:23:25

标签: firebase dart google-cloud-firestore flutter

我想使用Flutter和Firebase构建应用程序(Firestore版本cloud_firestore:^ 0.6.3)。 使用StreamBuilder从Firestore加载Collection时,在ListView中显示它 我收到一个错误说:

以下断言被抛出构建StreamBuilder(脏,状态: I / flutter(26287):_ StreamBuilderBaseState&gt;#d5638):

I / flutter(26287):类型'_InternalLinkedHashMap'不是'Map'类型的子类型

I / flutter(26287):其中

I / flutter(26287):_ InnerLinkedHashMap来自dart:collection

I / flutter(26287):地图来自dart:core

I / flutter(26287):字符串来自dart:core

I / flutter(26287):

我无法理解,因为即使在删除线条时也要使用 DocumentSnapshots会抛出错误。

这就是我想要访问快照中的字段的方式。

Creator.fromDoc(DocumentSnapshot doc) {
    this.creatorId = doc['creatorId'];
    this.name = doc['name'];
 }

或者

Creator.fromMap(doc.data);

Creator.fromMap(Map<String, dynamic> map) {
    if (map.containsKey('creatorId')) {
      this.creatorId = map['creatorId'];
    }
    if (map.containsKey('name')) {
      this.name = map['name'];
    }
  }

布局(没有来自上面的调用,但即使这会引发错误)。 这部分是从firestore示例中复制的。

 return new Scaffold(
            appBar: new AppBar(title: new Text('Creator')),
            body: new StreamBuilder<QuerySnapshot>(
                stream: CreatorRepo.getAllCreator(),
                builder:
                    (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
                  if (!snapshot.hasData) return new Text('Loading...');
                  return new ListView(
                    children: snapshot.data.documents.map<Widget>((DocumentSnapshot doc){
                      return new ExpansionTile(
                        title: new Text(doc['name']),
                        children: <Widget>[
                          new Text(doc['creatorId'])
                        ],
                      );
                    }).toList(),
                  );
                }));

编辑: 依赖关系:

dependencies:
  flutter:
    sdk: flutter
  cloud_firestore: ^0.6.3
  firebase_messaging: ^0.2.4
  cupertino_icons: ^0.1.0

dev_dependencies:
  flutter_test:
    sdk: flutter
flutter:
  uses-material-design: true

flutter clean帮助但导致了另一个错误:

Note: C:\Program Files\flutter\.pub-cache\hosted\pub.dartlang.org\firebase_core-0.2.3\android\src\main\java\io\flutter\plugins\firebase\core\FirebaseCorePlugin.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.

此错误似乎对应用程序没有影响。

当我启动这个项目时,我检查了Firestore代码,而DocumentSnapshot中的数据对象的类型为Map&lt;字符串,动态&gt;所以我认为对象内的每个地图都属于那种类型。 但要访问对象的这些子映射,您需要假设该Map的类型为Map&lt;动态,动态&gt;。每次我试图访问一个地图 地图&lt;字符串,动态&gt;它会崩溃改变它来访问对象的这些子映射,你需要假设该Map的类型为Map&lt;动态,动态&gt;暂时停止了崩溃。

5 个答案:

答案 0 :(得分:5)

我认为这是因为从Firebase返回的地图不是0,而是#include <stdio.h> #include <stdlib.h> struct my_struct { char** words; int length; } my_struct; int main(void) { struct my_struct list = { 0,0 }; list.words = (char**)malloc(0); int choice = 1, i = 0; char str[30]; printf("Enter 0 to exit or any other number to continue: "); scanf("%d", &choice); while (choice) { list.length += 1; list.words = (char**)realloc(list.words, sizeof(char*) * list.length); printf("Enter a word: "); getchar(); fgets(str, 30, stdin); list.words[list.length - 1] = (char*)malloc(sizeof(char) * 30); list.words[list.length - 1] = str; printf("Enter 0 to exit or any other number to continue: "); scanf("%d", &choice); } printf("Values:\n"); for (i = 0; i < list.length; i++) { printf("%s", list.words[i]); } free(list.words); getchar(); getchar(); return 0; }

有关相关问题,请参阅https://github.com/flutter/flutter/issues/17417

答案 1 :(得分:1)

Flutter现在可以与public class WebServiceCall { private static final String TAG = WebServiceCall.class.getSimpleName(); private static TrustManager[] trustManagers; public static String callWSThreadSoapPrimitive(String strURL, String strSoapAction, SoapObject request) { try { StringBuffer result; SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); envelope.dotNet = true; envelope.setOutputSoapObject(request); // certificat SSL allowAllSSL(); HttpTransportSE ht = new HttpTransportSE(strURL); List<HeaderProperty> llstHeadersProperty = new ArrayList<>(); llstHeadersProperty.add(new HeaderProperty("Authorization", "Basic " + org.kobjects.base64.Base64.encode("user:password".getBytes()))); ht.debug = true; ht.call(strSoapAction, envelope,llstHeadersProperty); SoapPrimitive response = (SoapPrimitive) envelope.getResponse(); result = new StringBuffer(response.toString()); Log.i(TAG, "result: " + result.toString()); return result.toString(); } catch (Exception e) { e.printStackTrace(); return null; } } public static class _FakeX509TrustManager implements javax.net.ssl.X509TrustManager { private static final X509Certificate[] _AcceptedIssuers = new X509Certificate[] {}; public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { } public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { } public boolean isClientTrusted(X509Certificate[] chain) { return (true); } public boolean isServerTrusted(X509Certificate[] chain) { return (true); } public X509Certificate[] getAcceptedIssuers() { return (_AcceptedIssuers); } } public static void allowAllSSL() { javax.net.ssl.HttpsURLConnection .setDefaultHostnameVerifier(new HostnameVerifier() { public boolean verify(String hostname, SSLSession session) { return true; } }); javax.net.ssl.SSLContext context = null; if (trustManagers == null) { trustManagers = new javax.net.ssl.TrustManager[] { new _FakeX509TrustManager() }; } try { context = javax.net.ssl.SSLContext.getInstance("TLS"); context.init(null, trustManagers, new SecureRandom()); } catch (NoSuchAlgorithmException e) { Log.e("allowAllSSL", e.toString()); } catch (KeyManagementException e) { Log.e("allowAllSSL", e.toString()); } javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(context .getSocketFactory()); }

一起使用

答案 2 :(得分:1)

使用Map<String, dynamic>.from ( mapFromFirestore )。假设mapFromFirestrore中的值是String值的dynamic键。

答案 3 :(得分:0)

我也遇到了这个问题,并用-

解决了这个问题。
<ion-label>

而不是未指定的Map。

<ion-col>

答案 4 :(得分:0)

你可以试试这个:

var stringMap = mapFromFirestore.map((key,value) => MapEntry(key as String, dynamic.from(value));