【问题标题】:Firebase Database change node IDFirebase 数据库更改节点 ID
【发布时间】:2017-11-18 04:21:22
【问题描述】:

如何更改下图中子节点的命名? questions_statsList<Integer>,我知道我将整数作为节点 ID,因为这是一个列表。我用 0 到 1000 之间的数字随机创建每个孩子。我将此 ID 设置为对象的一部分,并在列表中循环找到它。我想要的是在我创建它的那一刻将“0671”设置为对象的键。

我应该如何定义我的对象,以便使用我定义为字符串的 Id 访问每个孩子。

每个questions_stats 都是一个对象。

这是我的 UserProfile 类定义。

public class UserProfile implements Parcelable {
    private List<Integer> questions_list;
    private List<QuestionsStats> questions_stats;
    private String country_name, share_code, user_name;
    private int token_count;
    private Boolean is_guest;

    public UserProfile() {
    }

    public UserProfile(List<Integer> questions_list, List<QuestionsStats> questions_stats, String country_name, String share_code, String user_name, int token_count, Boolean is_guest) {
        this.questions_list = questions_list;
        this.questions_stats = questions_stats;
        this.country_name = country_name;
        this.share_code = share_code;
        this.user_name = user_name;
        this.token_count = token_count;
        this.is_guest = is_guest;
    }
 }

我知道我可以单独使用child("0159").setValue(QuestionStats) 设置它们。

但出于我的目的,我需要整体检索 "user" 的数据,然后像列表一样在 questions_stats 中进行迭代。

我应该如何定义我的 UserProfile 类以实现我想要的?

谁能给我一个提示?

【问题讨论】:

  • @Peter Haddad questions_stats 是一个对象列表,因为列表 0 和 1 是索引。我想要的是能够将“0001”或“8760”之类的键设置为特定对象,并以 Map 而不是列表的形式访问 questions_stats。我可以使用四循环访问列表中的特定对象,但我相信使用 Map 会提高效率。不知道如何实现 Map。
  • Firebase 数据库是一个 NoSQL 数据库,其结构为一对 key 和 veales,这意味着数据库中的每个节点都是一个 Map。看到你的数据库截图,question_stats 也是一个Map,其中question_stats 是一个键,它下面的数据是一个值。 0 节点也是一个映射,其中0 作为键,它下面的数据作为值。等等。不要对模型类中有一个列表感到困惑。在数据库中,每个节点都是一个Map

标签: android json firebase firebase-realtime-database hashmap


【解决方案1】:

How can I change the node names of my children in the image below?

回答:有 no way,您可以在其中更改 Firebase 数据库中的节点名称。没有 API 可以做到这一点。您可以做的是在该节点上附加一个侦听器并获取dataSnapshot 对象。有了这些数据,您可以使用其他名称将其写入另一个地方。您不能简单地将它们重命名为from 0 to 00001 to 0001 等等。

【讨论】:

  • 我相信有一种方法可以使用 Map 来设置名称。我只是不知道如何在我的模型中实现它。不想重命名,我想在更新“用户”时设置密钥(节点名称)。
  • 即使使用Map&lt;String, Object&gt;,也不能简单地更改节点的名称。这与您的模型无关,它与 Firebase 无关,它不提供任何允许您重命名节点的工具。当您要设置密钥(节点密钥)时,意味着您要更新该密钥,这在 Firebase 中是不可能的。正如我在上面提到的那样,您可以实现这一目标的唯一方法。从当前位置获取数据,使用另一个名称将其写入另一个位置,从旧位置删除记录。
  • 不想重命名,因为它的节点ID是一个索引,因为questions_stats是一个List。我想要的是第一次创建一个节点时用一个字符串命名它,这样我以后可以访问它来修改它的内容。一旦我创建它,我就不需要重命名它。我检索用户作为一个整体操作其数据并更新它。我可以使用 For 循环来处理它,但我不相信它是有效的。
  • 您也可以按原样工作。我看不到效率问题。这就是 Firebase 的工作方式。您的代码和数据库都没有问题。你可以继续。
  • 最终我将在 questions_stats 下拥有超过 500 个节点。知道我想要访问的值的名称我认为它会比遍历列表更好。如果我随机选择一个对象“6791”并将其添加到我的空 questions_stats 列表中,它将把它放在索引 0 中。相反,我想从添加它的那一刻起用“6791”键它
【解决方案2】:

也许我应该询问如何“设置”节点 ID 而不是“更改” 我拥有的是List&lt;QuestionsStats&gt;,但是当使用List&lt;QuestionsStats&gt; 时,您会得到索引作为键,我想要的是拥有相同的List&lt;QuestionsStats&gt;,但不是索引,而是我的每个项目的字符串键。 所以我将我的列表更改为Map&lt;String, QuestionsStats&gt;。现在棘手的部分是在打包Object 时。您可以使用 readMap()writeMap() 进行包裹,如@David Wasser 在此答案中显示的here 所示,但它会发出警告:

请改用 writeBundle(Bundle)。将地图展平到地块中 在当前 dataPosition() 处,如果需要,增加 dataCapacity()。这 映射键必须是字符串对象。地图值是使用编写的 writeValue(Object) 并且必须遵循那里的规范。它是 强烈建议使用 writeBundle(Bundle) 而不是这个 方法,因为 Bundle 类提供了一个类型安全的 API,它允许 您可以避免在编组时出现神秘的类型错误。

因此,在This Question 中的 cmets 的帮助下,我使用此代码打包,请注意,如果有人发现它有用或对此有任何评论,我将留下“简单”的评论方式:

    protected UserProfile(Parcel in) {
//        in.readMap(myMap, Object.class.getClassLoader());
        myMap = new HashMap<>();
        String[] array = in.createStringArray();
        Bundle bundle = in.readBundle(Object.class.getClassLoader());
        for (String s : array) {
            myMap.put(s, (Object) bundle.getParcelable(s));
        }
    }


    @Override
    public void writeToParcel(Parcel dest, int flags) {


    //        dest.writeMap(myMap);
            Bundle bundle = new Bundle();
            for (Map.Entry<String, Object> entry : myMap.entrySet()) {
                bundle.putParcelable(entry.getKey(), entry.getValue());
            }
            Set<String> keySet = myMap.keySet();
            String[] array = keySet.toArray(new String[keySet.size()]);
            dest.writeStringArray(array);
            dest.writeBundle(bundle);
        }

为什么我想要这个,目前我的列表包含不到 100 个项目,但它可能会增长到 1000 个,我不是专业人士,但我相信如果我已经知道项目的关键,我就是感兴趣总是比遍历列表来找到它要好。最后我的主要问题是Map的用法,我不知道怎么做。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-12
    相关资源
    最近更新 更多