Java 如何从 Firestore 获取数组?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/50233281/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get an array from Firestore?
提问by Simon Ho
I have the above data structure stored in Cloud Firestore. I want to save the dungeon_group
which is an array of strings stored in Firestore.
我将上述数据结构存储在 Cloud Firestore 中。我想保存dungeon_group
存储在 Firestore 中的字符串数组。
I have difficulty in getting the data and stored as an array. I am just able to get a weird string but any method to store as a string array? Below is the code I used.
我很难获取数据并存储为数组。我只能得到一个奇怪的字符串,但是有什么方法可以存储为字符串数组?下面是我使用的代码。
I am able to achieve this in Swift as follow, but not sure how to do the same in Android.
我能够在 Swift 中实现这一点,如下所示,但不确定如何在 Android 中做到这一点。
//Swift
//迅速
Firestore.firestore().collection("dungeon").document("room_en").getDocument { (document, error) in
if let document = document {
let group_array = document["dungeon_group"] as? Array ?? [""]
print(group_array)
}
}
//JAVA Android
//JAVA安卓
FirebaseFirestore.getInstance().collection("dungeon").document("room_en").get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
@Override
public void onComplete(@NonNull Task<DocumentSnapshot> task) {
DocumentSnapshot document = task.getResult();
String group_string= document.getData().toString();
String[] group_array = ????
Log.d("myTag", group_string);
}
});
Console OutPut as the follow:{dungeon_group=[3P, Urgent, Mission Challenge, Descended, Collaboration, Daily, Technical, Normal]}
控制台输出如下:{dungeon_group=[3P, Urgent, Mission Challenge, Descended, Collaboration, Daily, Technical, Normal]}
采纳答案by Doug Stevenson
When you call DocumentSnapshot.getData(), it returns a Map. You're just calling toString() on that map, which is going to give you a dump of all the data in the document, and that's not particularly helpful. You need to access the dungeon_group
field by name:
当您调用DocumentSnapshot.getData() 时,它会返回一个 Map。您只是在该地图上调用 toString() ,这将为您提供文档中所有数据的转储,这并不是特别有用。您需要dungeon_group
按名称访问该字段:
DocumentSnapshot document = task.getResult();
List<String> group = (List<String>) document.get("dungeon_group");
- edit: syntax error in typecasting
- 编辑:类型转换中的语法错误
回答by Alex Mamo
If you want to get the entire dungeon_group
array you need to iterate over a Map
like this:
如果你想获得整个dungeon_group
数组,你需要Map
像这样迭代:
Map<String, Object> map = documentSnapshot.getData();
for (Map.Entry<String, Object> entry : map.entrySet()) {
if (entry.getKey().equals("dungeon_group")) {
Log.d("TAG", entry.getValue().toString());
}
}
But note, even if the dungeon_group
object is stored in the database as an array, entry.getValue()
returns an ArrayList
and notan array.
但请注意,即使dungeon_group
对象作为数组存储在数据库中,也会entry.getValue()
返回一个ArrayList
而不是数组。
A better approach for you would be if you consider this alternative database structure, in which each group
is the key in a Map
and all values are set to the boolean true
:
如果您考虑这种替代数据库结构,对您来说更好的方法是,其中每个group
都是 a 中的键,Map
并且所有值都设置为 boolean true
:
dungeon_group: {
3P: true,
Urgent: true,
Mission Chalange: true
//and so on
}
Using this structure you'll also be able to query it based on property that exist within the dungeon_group
map, otherwise as in the official documentation:
使用此结构,您还可以根据dungeon_group
地图中存在的属性查询它,否则在官方文档中:
Although Cloud Firestore can store arrays,
it does not support
querying array members or updating single array elements.
虽然 Cloud Firestore 可以存储数组、
it does not support
查询数组成员或更新单个数组元素。
Edit 13 Aug 2018:
2018 年 8 月 13 日编辑:
According to the updated documentation regarding array membership, now it is possible to filter data based on array values using whereArrayContains()
method. A simple example would be:
根据有关数组成员资格的更新文档,现在可以使用whereArrayContains()
方法基于数组值过滤数据。一个简单的例子是:
CollectionReference citiesRef = db.collection("cities");
citiesRef.whereArrayContains("regions", "west_coast");
This query returns every city document where the regions field is an array that contains west_coast. If the array has multiple instances of the value you query on, the document is included in the results only once.
此查询返回每个城市文档,其中区域字段是包含 west_coast 的数组。如果数组具有您查询的值的多个实例,则该文档仅包含在结果中一次。
回答by Francisco Durdin Garcia
There are two solutions for your problem, one, you can cast the value from your document in the next way:
您的问题有两种解决方案,一种是您可以通过以下方式从文档中转换值:
DocumentSnapshot document = task.getResult();
List<String> dungeonGroup = (List<String) document.get("dungeon_group");
Or, and I would recommend you this solution because there is always a possibility that your model will change when you are developing your app. This solution is just model everything in Firebase POJO's even if they have just one parameter:
或者,我会向您推荐这个解决方案,因为在您开发应用程序时,您的模型总是有可能发生变化。此解决方案只是对 Firebase POJO 中的所有内容进行建模,即使它们只有一个参数:
public class Dungeon {
@PropertyName("dungeon_group")
private List<String> dungeonGroup;
public Dungeon() {
// Must have a public no-argument constructor
}
// Initialize all fields of a dungeon
public Dungeon(List<String> dungeonGroup) {
this.dungeonGroup = dungeonGroup;
}
@PropertyName("dungeon_group")
public List<String> getDungeonGroup() {
return dungeonGroup;
}
@PropertyName("dungeon_group")
public void setDungeonGroup(List<String> dungeonGroup) {
this.dungeonGroup = dungeonGroup;
}
}
Remember that you can use the Annotation @PropertyName to avoid call your variables in the same way that your value in the database. Doing it in this way finally you can just do:
请记住,您可以使用 Annotation @PropertyName 来避免以与您在数据库中的值相同的方式调用您的变量。以这种方式最终做到这一点,您可以这样做:
DocumentSnapshot document = task.getResult();
Dungeon dungeon= toObject(Dungeon.class);
Hope that it will help you! Happy coding!
希望它会帮助你!快乐编码!
回答by Aminu Bishir
Since Your document looks like this "dongeon_group=[SP, urgent, missinon challenge,...]
when you convert it to string, say via String.valueOf(document.getData())
由于您的文档"dongeon_group=[SP, urgent, missinon challenge,...]
在将其转换为字符串时看起来像这样,例如通过String.valueOf(document.getData())
I think another way to simply achieve this is by unpacking the document right away into a string of array as follows:
我认为另一种简单地实现这一点的方法是将文档立即解压缩为一串数组,如下所示:
String[] unpackedDoc = document.getData().entrySet().toArray()[0].toString().split("=")[1].split(",");
String[] unpackedDoc = document.getData().entrySet().toArray()[0].toString().split("=")[1].split(",");
Explanation
解释
The document
is gotten from documentSnapshot.getDocuments()
which return a list containing you documents.
在document
从被得到documentSnapshot.getDocuments()
它返回包含您的文档列表。
Since your documents, from the firestore, seem to be nested, calling the document.getData()
will return the list, a list with single element of course, of your document.
document.getData().entrySet()
will make the document ready to be converted to array (you can't do that with getData() alone) also containing single element.
Accessing the single element document.getData().entrySet().toArray()[0]
and then converting it to string, document.getData().entrySet().toArray()[0].toString()
will leave with a string that you can then split (using the =
found in the string) and then take the second part.
The second part can also be split into an array containing the values of your document.
由于您的文档,来自 firestore,似乎是嵌套的,调用document.getData()
将返回列表,当然,一个包含单个元素的列表,您的文档。
document.getData().entrySet()
将使文档准备好转换为数组(您不能单独使用 getData() 来做到这一点)也包含单个元素。访问单个元素document.getData().entrySet().toArray()[0]
,然后将其转换为字符串,document.getData().entrySet().toArray()[0].toString()
将留下一个字符串,您可以将其拆分(使用=
在字符串中找到的),然后获取第二部分。第二部分也可以拆分为包含文档值的数组。
Since this solution convert one element at a time, you can wrap it within a loop so you can convert all the documents available.
由于此解决方案一次转换一个元素,因此您可以将其包装在一个循环中,以便您可以转换所有可用的文档。
For example:
例如:
for(DocumentSnapshot document :documentSnapshot.getDocuments()){
String[] unpackedDoc = document.getData().entrySet().toArray()[0].toString().split("=")[1].split(",");
//do something with the unpacked doc
for(DocumentSnapshot document :documentSnapshot.getDocuments()){
String[] unpackedDoc = document.getData().entrySet().toArray()[0].toString().split("=")[1].split(",");
//do something with the unpacked doc
}
}