Добавление новых значений в Remote Config JSON

У меня есть один JSON, хранящийся в Remote Config, который содержит большую часть текста моего приложения. Если я добавлю пару "ключ-значение" к удаленному объекту и объекту JSON по умолчанию, а затем попытаюсь сослаться на это значение от клиента, клиент попытается получить доступ к значению в старом кэшированном JSON и вернет значение null, даже если значение хранится в новый JSON по умолчанию жестко запрограммирован в клиенте приложения.

Как я могу полагаться на обновленное значение по умолчанию, если обновленный удаленный JSON еще не кэширован? Другие предложения также приветствуются.

Как сделать HTTP-запрос в Javascript?
Как сделать HTTP-запрос в Javascript?
В JavaScript вы можете сделать HTTP-запрос, используя объект XMLHttpRequest или более новый API fetch. Вот пример для обоих методов:
0
0
52
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я создал синглтон, в котором хранится текст json моего приложения по умолчанию, а также удаленный json.

В main() я вызываю AppTextSingleton();, а затем запускаю await AppTextSingleton.singleton.initialize(); после инициализации RemoteConfig. Я делаю все это до того, как мне позвонят runApp.

appText синглтона содержит все кешированные удаленные значения, а также любые значения по умолчанию, которых нет в кешированном удаленном json. Таким образом, если приложение обновляется до новой версии, которая вызывает новую пару ключ-значение из JSON, но клиент все еще работает со старой кешированной версией без пары ключ-значение, будет использоваться значение по умолчанию. .

import 'dart:convert';
import 'package:flutter/services.dart';
import '../constants.dart';

class AppTextSingleton {
  Map<String, dynamic> remoteAppText =
      json.decode(remoteConfig.getString("app_text"));
  Map<String, dynamic> defaultAppText = {};
  Map<String, dynamic> appText =
      json.decode(remoteConfig.getString("app_text"));

  factory AppTextSingleton() => singleton;
  static final AppTextSingleton singleton = AppTextSingleton._internal();
  AppTextSingleton._internal();

  Future<void> initialize() async {
    await setDefaultAppText();
    mergeTexts();
  }

  Future<void> setDefaultAppText() async {
    defaultAppText = await json
        .decode(await rootBundle.loadString('assets/default_text.json'));
  }

  void mergeTexts() {
      appText = mergeMap([defaultAppText, remoteAppText], acceptNull: true);
  }
}

mergeMap является модифицированной версией пакета [belatuk_merge_map 4.0.0]1. Просто скопировал один файл дротика в пакете в локальный проект и изменил функцию _copyValues, чтобы добавить только карты типа <String, dynamic>. Текущий пакет, кажется, добавляет <dynamic, dynamic>, что не соответствует потребностям RemoteConfig.

Модифицированный пакет:

dynamic _copyValues<K, V>(Map<String, dynamic> from, Map<String, dynamic> to,
    bool recursive, bool acceptNull) {
  for (var key in from.keys) {
    if (from[key] is Map<String, dynamic> && recursive) {
      if (to[key] is! Map<String, dynamic>) {
        to[key] = <String, dynamic>{};
      }
      _copyValues(from[key] as Map<String, dynamic>,
          to[key] as Map<String, dynamic>, recursive, acceptNull);
    } else {
      if (from[key] != null || acceptNull) {
        to[key] = from[key];
      }
    }
  }
}

Map<String, dynamic> mergeMap<K, V>(Iterable<Map<String, dynamic>> maps,
    {bool recursive = true, bool acceptNull = false}) {
  var result = <String, dynamic>{};
  for (var map in maps) {
    _copyValues(map, result, recursive, acceptNull);
  }
  return result;
}

Другие вопросы по теме