The old code in this answer contained bugs! Because of that, I thoroughly coded it new.
Firebase uses a timestamp to ensure the chronological order of the generated keys.
I wrote a method to lexicographically invert a key (in a bijective way), so all order relations between two keys still exist, but in reverse. So if key1 > key2, then after that key1 < key2.
New code:
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())
}
}
Usage:
String key = reference.pushKey();
String invertedKey = InvertiereKey.invertiereKey(key);
reference.child(invertedKey).setValue(...);