【问题标题】:Firebase Android: push().getKey() but insert element at beginning, not at the endFirebase Android:push().getKey() 但在开头插入元素,而不是在结尾
【发布时间】:2022-01-25 19:47:35
【问题描述】:
String key = databaseReference.child("Photo").push().getKey();
// ...
databaseReference.child("Photo").child(key).setValue(post);

据我所知,Firebase 在这里创建了一个有统计保证的唯一 ID,并且它还有一个订单。我查了一下,确实有订单。像这样,它总是在数据结构的末尾插入新元素。比如这样:

-MqWU0En0OezPglE6SfL: true
-MqWUFoFqhIaT6fSk-DT: true
-MrmJaNZ8lbcOFPodTBO: true

变成:

-MqWU0En0OezPglE6SfL: true
-MqWUFoFqhIaT6fSk-DT: true
-MrmJaNZ8lbcOFPodTBO: true
-Mrq162Eba8KHgc_B0lh: true (New Element was inserted here at the end!)

我需要反其道而行之。我需要在开头插入它。有没有办法做到这一点?也许像push().getKeyAtBeginning() 这样的东西?我找不到任何东西。


如果没有,你有什么建议?

在孩子中,photo 是成千上万张照片。我知道您可以在每张具有-1 * currentMillis 值的照片中插入一个子元素negativetimestamp,然后只需使用orderByChild(negativetimestamp)。但我认为这不是一个好主意,因为届时 Firebase 必须订购成千上万甚至上万张照片。

【问题讨论】:

    标签: android firebase firebase-realtime-database google-cloud-platform


    【解决方案1】:

    不幸的是,你无法使用这样的东西:

    push().getKeyAtBeginning()
    

    您不能将节点添加到特定索引。除此之外,您也无法更改Firebase Console 中节点的顺序。所有节点默认按key排序。

    如果您需要按特定标准对元素进行排序,那么您的想法就是前进的道路。我也回答了一个类似的问题:

    如果有数千甚至一万张照片,那么您应该考虑将它们分成更小的块。这种方法称为pagination

    【讨论】:

    • 您的意思是分页已经在 Firebase 中的数据存储中吗?或者只是分页以获取您提到的链接中的项目。因为在后一种情况下,我仍然遇到订单错误的问题。但是,我找到了一种适合我的方法并将其发布为答案。我不确定这是否是好的风格,因为它肯定不是 Firebase 想要的方式。那么你能告诉我我在那里使用的方法是否会随着时间的推移而出现任何问题?
    • 分页只是为了获取项目,如我提到的链接中所示。没有看到代码,我不能说你为什么得到错误的订单。但是如果正确添加了时间戳,那么它肯定会起作用,如果你反转长数字,无论是升序还是降序。
    • 不,我的意思是,我会得到正确的顺序,但 Firebase 仍然必须每次对一万个元素进行排序。它发生在服务器端,假设每页只有 20 个项目,但 Firebase 仍然必须订购所有一万个项目,不是吗?因为否则它怎么知道退货的顺序?
    【解决方案2】:

    此答案中的旧代码包含错误!因此,我将其彻底编码为新代码。


    Firebase 使用时间戳来确保生成的密钥的时间顺序。 我编写了一个按字典顺序反转键的方法(以双射方式),因此两个键之间的所有顺序关系仍然存在,但相反。所以如果key1 > key2,那么在key1


    新代码:

    import java.util.HashMap;
    import java.util.Map;
    
    public class InvertiereKey {
    
        /**
         * all allowed chars for a firebase key in a lexicographical order (except SPACE)
         */
        private static Map<Integer, String> hashtable;
    
        private static void initHash() {
            if (hashtable == null) {
                hashtable = new HashMap<>();
    
                hashtable.put(0, "!");
                hashtable.put(1, "\"");
                hashtable.put(2, "%");
                hashtable.put(3, "'");
                hashtable.put(4, "(");
                hashtable.put(5, ")");
                hashtable.put(6, "*");
                hashtable.put(7, "+");
                hashtable.put(8, ",");
                hashtable.put(9, "-");
                //hashtable.put(10, "/"); // This does NOT work because child("a/b") means child("a").child("b")
                hashtable.put(10, "0");
                hashtable.put(11, "1");
                hashtable.put(12, "2");
                hashtable.put(13, "3");
                hashtable.put(14, "4");
                hashtable.put(15, "5");
                hashtable.put(16, "6");
                hashtable.put(17, "7");
                hashtable.put(18, "8");
                hashtable.put(19, "9");
                hashtable.put(20, ":");
                hashtable.put(21, ";");
                hashtable.put(22, "<");
                hashtable.put(23, "=");
                hashtable.put(24, ">");
                hashtable.put(25, "?");
                hashtable.put(26, "@");
                hashtable.put(27, "A");
                hashtable.put(28, "B");
                hashtable.put(29, "C");
                hashtable.put(30, "D");
                hashtable.put(31, "E");
                hashtable.put(32, "F");
                hashtable.put(33, "G");
                hashtable.put(34, "H");
                hashtable.put(35, "I");
                hashtable.put(36, "J");
                hashtable.put(37, "K");
                hashtable.put(38, "L");
                hashtable.put(39, "M");
                hashtable.put(40, "N");
                hashtable.put(41, "O");
                hashtable.put(42, "P");
                hashtable.put(43, "Q");
                hashtable.put(44, "R");
                hashtable.put(45, "S");
                hashtable.put(46, "T");
                hashtable.put(47, "U");
                hashtable.put(48, "V");
                hashtable.put(49, "W");
                hashtable.put(50, "X");
                hashtable.put(51, "Y");
                hashtable.put(52, "Z");
                hashtable.put(53, "\\");
                hashtable.put(54, "^");
                hashtable.put(55, "_");
                hashtable.put(56, "`");
                hashtable.put(57, "a");
                hashtable.put(58, "b");
                hashtable.put(59, "c");
                hashtable.put(60, "d");
                hashtable.put(61, "e");
                hashtable.put(62, "f");
                hashtable.put(63, "g");
                hashtable.put(64, "h");
                hashtable.put(65, "i");
                hashtable.put(66, "j");
                hashtable.put(67, "k");
                hashtable.put(68, "l");
                hashtable.put(69, "m");
                hashtable.put(70, "n");
                hashtable.put(71, "o");
                hashtable.put(72, "p");
                hashtable.put(73, "q");
                hashtable.put(74, "r");
                hashtable.put(75, "s");
                hashtable.put(76, "t");
                hashtable.put(77, "u");
                hashtable.put(78, "v");
                hashtable.put(79, "w");
                hashtable.put(80, "x");
                hashtable.put(81, "y");
                hashtable.put(82, "z");
                hashtable.put(83, "{");
                hashtable.put(84, "|");
                hashtable.put(85, "}");
                hashtable.put(86, "~");
            }
        }
    
        
        /**
         * um andere einfuege reihenfolge von push().getKey() bei firebase zu haben
         * Also am anfang wird eingefuegt dann, nicht ans ende
         *
         * @param key
         * @return
         */
        public static String invertiereKey(String key) {
            initHash();
    
            String invertiert = "";
    
            // get char array
            char[] charArray = key.toCharArray();
    
            // iterate over it and invert every char lexicographically
            int i = 0;
            while (i < charArray.length) {
                char charTemp = charArray[i];
    
                // get numerical value
                int numerical = getNumericalFromChar(charTemp);
    
                // invert the numerical representation
                // there are 88 chars
                // 0 --> first char, 87 --> last char
                int numericalNeu = 87 - numerical;
    
                // get char again
                String newChar = hashtable.get(numericalNeu);
    
                // add to inverted string
                invertiert += newChar;
    
                i++;
            }
    
            return invertiert;
        }
    
        private static int getNumericalFromChar(char c) {
            String s = Character.toString(c);
    
            for (Map.Entry<Integer, String> entry : hashtable.entrySet()) {
                if (s.equals(entry.getValue())) {
                    return entry.getKey();
                }
            }
    
            return 0; // never called with proper input (ie. a firebase key generated from pushKey())
        }
    }
    

    用法:

    String key = reference.pushKey();
    String invertedKey = InvertiereKey.invertiereKey(key);
    reference.child(invertedKey).setValue(...);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-01-20
      • 1970-01-01
      • 2016-03-08
      • 2022-01-15
      • 1970-01-01
      • 2011-10-31
      • 1970-01-01
      相关资源
      最近更新 更多