我想使用Flutter和Firebase构建应用程序(Firestore版本cloud_firestore:^ 0.6.3)。 使用StreamBuilder从Firestore加载Collection时,在ListView中显示它 我收到一个错误说:
以下断言被抛出构建StreamBuilder(脏,状态: I / flutter(26287):_ StreamBuilderBaseState>#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;暂时停止了崩溃。
答案 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;
}
。
答案 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));