66 lines
2.0 KiB
Dart
Executable File
66 lines
2.0 KiB
Dart
Executable File
// Copyright 2017, the Chromium project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
import 'dart:math';
|
|
|
|
/// Utility class for generating Firebase child node keys.
|
|
///
|
|
/// Since the Flutter plugin API is asynchronous, there's no way for us
|
|
/// to use the native SDK to generate the node key synchronously and we
|
|
/// have to do it ourselves if we want to be able to reference the
|
|
/// newly-created node synchronously.
|
|
///
|
|
/// This code is based on a Firebase blog post and ported to Dart.
|
|
/// https://firebase.googleblog.com/2015/02/the-2120-ways-to-ensure-unique_68.html
|
|
class PushIdGenerator {
|
|
static const String PUSH_CHARS =
|
|
'-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz';
|
|
|
|
static final Random _random = Random();
|
|
|
|
static int? _lastPushTime;
|
|
|
|
static final List<int?> _lastRandChars =
|
|
List<int?>.filled(12, null, growable: false);
|
|
|
|
static String generatePushChildName() {
|
|
int now = DateTime.now().millisecondsSinceEpoch;
|
|
final bool duplicateTime = (now == _lastPushTime);
|
|
_lastPushTime = now;
|
|
|
|
final List<String?> timeStampChars =
|
|
List<String?>.filled(8, null, growable: false);
|
|
for (int i = 7; i >= 0; i--) {
|
|
timeStampChars[i] = PUSH_CHARS[now % 64];
|
|
now = (now / 64).floor();
|
|
}
|
|
assert(now == 0);
|
|
|
|
final StringBuffer result = StringBuffer(timeStampChars.join());
|
|
|
|
if (!duplicateTime) {
|
|
for (int i = 0; i < 12; i++) {
|
|
_lastRandChars[i] = _random.nextInt(64);
|
|
}
|
|
} else {
|
|
_incrementArray();
|
|
}
|
|
for (int i = 0; i < 12; i++) {
|
|
result.write(PUSH_CHARS[_lastRandChars[i]!]);
|
|
}
|
|
assert(result.length == 20);
|
|
return result.toString();
|
|
}
|
|
|
|
static void _incrementArray() {
|
|
for (int i = 11; i >= 0; i--) {
|
|
if (_lastRandChars[i] != 63) {
|
|
_lastRandChars[i] = _lastRandChars[i]! + 1;
|
|
return;
|
|
}
|
|
_lastRandChars[i] = 0;
|
|
}
|
|
}
|
|
}
|