简体   繁体   中英

Flutter: How to download Json file to local then access it

Currently, I am accessing a specific JSON file country.json by DefaultAssetBundle as follows:

Future<List<Country>> getCountryFromJson(BuildContext context) async {
    String jsonString =
        await DefaultAssetBundle.of(context).loadString('assets/country.json');
    List<dynamic> raw = jsonDecode(jsonString);
    return raw.map((e) => Country.fromJson(e)).toList();
  }

However I want to update new json file (same name) by uploading it to FirebaseStorage , then every time the app open, it will download new file via get http and access it later (the app still accesses the old file when the new file hasn't finished downloading)

So I want to ask how to do the following:

- Option 1: Download the new file country.json from Http link and overwrite to the old file in assets
- Option 2: If it is unable to interfere with the assets, then download it to wherever possible in local storage and prioritize access to the new file over the old file in the assets

this is the main file:

import 'dart:convert';
import 'dart:core';
import 'package:ask/country.dart';
import 'package:flutter/material.dart';


void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  Future<List<Country>> getCountryFromJson(BuildContext context) async {
    String jsonString =
        await DefaultAssetBundle.of(context).loadString('assets/country.json');
    List<dynamic> raw = jsonDecode(jsonString);
    return raw.map((e) => Country.fromJson(e)).toList();
  }

  Widget build(BuildContext context) {
    return new MaterialApp(
        home: Scaffold(
            appBar: AppBar(title: Text('Country')),
            body: Container(
                child: FutureBuilder(
                    future: getCountryFromJson(context),
                    builder: (context, data) {
                      if (data.hasData) {
                        List<Country> countries = data.data;
                        return ListView.builder(
                            itemCount: countries.length,
                            itemBuilder: (context, index) {
                              return Padding(
                                  padding: const EdgeInsets.all(5.0),
                                  child: Column(children: <Widget>[
                                    Text(
                                      countries[index].country,
                                    )
                                  ]));
                            });
                      } else {
                        return Center(child: CircularProgressIndicator());
                      }
                    }))));
  }
}

You can follow thisguide on Firebase Cloud Storage for downloading files in Flutter. Steps on how to upload files to Cloud Storage is also discussed in the docs. Then to update the local json file, you can read the json and map it to a model/Object or List.

File file = File('${PATH}/country.json');
String jsonText = await file.readAsString();

final parsed = jsonText(responseBody).cast<Map<String, dynamic>>(););

List<Country> listCountry = parsed.map<Photo>((json) => Country.fromJson(json)).toList();

Then you can insert another Country in the List by using either List.insert(index, Object) or List.add(Object) . If you need help serializing json to a model for adding a new entry in the List, you can check out this guide .

The model for Country could look something like this.

class Country {
  final int countryId;
  final int countryName;

  const Country({
    required this.countryId,
    required this.countryName,
  });

  factory Country.fromJson(Map<String, dynamic> json) {
    return Photo(
      countryId: json['country_id'] as String,
      countryName: json['country_name'] as String,
    );
  }
}

However, since you're already using Firebase products, you might want to consider using Cloud Firestore since the use case that you're describing seems to match the feature of Firestore.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM