我如何保存数据在共享的首选项和接收它到另一个页面的Flutter

lh80um4z  于 2022-12-30  发布在  Flutter
关注(0)|答案(2)|浏览(116)

我试图在共享首选项中保存数据。当我点击API时,使用id和pass它会给我令牌和id。我在共享首选项中保存了令牌,但无法保存userId。
但我想发送我的令牌和userId到另一个名为'lists.dart'的页面,并希望使用userId像snackbar或吐司等条件,所以userId和令牌必须需要保存在共享首选项中,并将用于获取数据的另一个页面。如何做到这一点?

这是API响应。

{token: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjI4OTksImlzcyI6Imh0dHBzOi8vcG9ydGFsLWFwaS5qb21ha2hhdGEuY29tL2FwaS9hdXRoL2xvZ2luIiwiaWF0IjoxNjI5Nzc4NTI3LCJleHAiOjE2Mjk4NjQ5MjcsIm5iZiI6MTYyOTc3ODUyNywianRpIjoiM25Xbkl3UVFGNE1YSWZVVCJ9.Q9dxnu-WWHA2p8n0oSEamLXDOPqdzsemnrlHHfiuV7o, message: success, userId: 2899, passwordChanged: yes}

这是API请求

Future<Album> createAlbum(String employee_custom_id, String password) async {
    SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
    final response = await http.post(
      Uri.parse('https://....com/api/auth/login'),
      headers: <String, String>{
        'Content-Type': 'application/json',
      },
      body: jsonEncode(<String, String>{
        'employee_custom_id': 1002899,
        'password': 000000,
      }),
    );

    final data = json.decode(response.body);
    if (response.statusCode == 200) {
      sharedPreferences.setString("token", data['token']);
      sharedPreferences.setInt("userId", data['userId']);

      log('$data');
      // print(id);

      return Album.fromJson(jsonDecode(response.body));
    } else {
      throw Exception('Failed to create album.');
    }
}

以下是完整代码

class _LoginPageState extends State<LoginPage> {
  final TextEditingController _emailController = TextEditingController();
  final TextEditingController _passwordController = TextEditingController();
  bool _validate = false;
  int charLength = 0;
  bool _status = false;

  _onChanged(String value) {
    setState(() {
      charLength = value.length;
    });

    if (charLength >= 4) {
      setState(() {
        _status = true;
      });
    } else {
      setState(() {
        _status = false;
      });
    }
  }

  Future<Album>? _futureAlbum;

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    Size size = MediaQuery
        .of(context)
        .size;
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Portal',
      home: Scaffold(
        body: Container(
          alignment: Alignment.center,
          padding: const EdgeInsets.all(8.0),
          child: buildColumn(),
        ),
      ),
    );
  }

  Column buildColumn() {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[

        TextField(
          controller: _emailController,
          keyboardType: TextInputType.text,
          autofocus: true,
          onChanged: _onChanged,
          decoration: InputDecoration(
            hintText: 'Email or ID',
            hintStyle: TextStyle(color: Colors.grey),
            filled: true,
            fillColor: Colors.white70,
            enabledBorder: OutlineInputBorder(
              borderRadius: BorderRadius.all(Radius.circular(12.0)),
              borderSide: BorderSide(color: Colors.purpleAccent, width: 2),
            ),
            focusedBorder: OutlineInputBorder(
              borderRadius: BorderRadius.all(Radius.circular(10.0)),
              borderSide: BorderSide(color: Colors.purpleAccent),
            ),

            prefixIcon: Icon(Icons.email),
          ),
        ),
        SizedBox(
          height: 20,
        ),
        TextField(
          controller: _passwordController,
          keyboardType: TextInputType.visiblePassword,
          autofocus: false,
          obscureText: false,
          decoration: InputDecoration(
            hintText: 'Password',
            hintStyle: TextStyle(color: Colors.grey),
            filled: true,
            fillColor: Colors.white70,
            enabledBorder: OutlineInputBorder(
              borderRadius: BorderRadius.all(Radius.circular(12.0)),
              borderSide: BorderSide(color: Colors.purpleAccent, width: 2),
            ),
            focusedBorder: OutlineInputBorder(
              borderRadius: BorderRadius.all(Radius.circular(10.0)),
              borderSide: BorderSide(color: Colors.purpleAccent),
            ),
            prefixIcon: Icon(Icons.lock),
            suffixIcon: Icon(Icons.visibility_off),
          ),
        ),
        SizedBox(
          height: 20,
        ),
        Visibility(
          maintainSize: true,
          maintainAnimation: true,
          maintainState: true,
          visible: _status,
          child: Container(
              margin: EdgeInsets.only(top: 20),
              child: Center(
                child: RaisedButton(
                  child: Text('Login'),
                  onPressed: () {
                    setState(() {
                      // in this position i want to make snackbar by using if-else condition with checking userId
                 
                      _futureAlbum =
                          createAlbum(_emailController.text, _passwordController.text);
                    });
                  },
                  color: Colors.green,
                  textColor: Colors.white,
                  padding: EdgeInsets.fromLTRB(10, 10, 10, 10),
                ),
              )
          ),
        )
      ],
    );
  }

  Future<Album> createAlbum(String employee_custom_id, String password) async {
    SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
    final response = await http.post(
      Uri.parse('https:.com/api/auth/login'),
      headers: <String, String>{
        'Content-Type': 'application/json',
      },
      body: jsonEncode(<String, String>{
        'employee_custom_id': employee_custom_id,  //1002899
        'password': password,  000000
      }),
    );

    final data = json.decode(response.body);
    if (response.statusCode == 200) {
      sharedPreferences.setString("token", data['token']);
      sharedPreferences.setInt("userId", data['userId']);

      log('$data');
      // print(id);

      return Album.fromJson(jsonDecode(response.body));
    } else {
      throw Exception('Failed to create album.');
    }
  }
}

class Album {
  final int id;
  final String employee_custom_id;
  final String password;

  Album({required this.id,
    required this.employee_custom_id,
    required this.password});

  factory Album.fromJson(Map<String, dynamic> json) {
    return Album(
      id: json['id'],
      employee_custom_id: json['title'],
      password: json['password'],
    );
  }
}

现在我想在我的lists.dart页面中接收“token”和“userId”。

Future<List<ListAlbum>> listData() async {

  final token = // token that i want to receiv from login page here.
  String url =
      'https://.com/api/getOrganizationData?token=${token}';

  Dio dio = new Dio();
  dio.options.headers['Content-Type'] = 'application/json';
  final body = {'limit': 100, 'orderBy': 'idEmployee', 'orderType': 'DESC'};
  final response = await dio.post(url, data: body);

  if (response.statusCode == 200) {
    print(response.statusCode);
    print(response.data);
    // sharedPreferences.setString("token", response.data['token']);

    return response.data["data"]["data"]
        .map<ListAlbum>((json) => ListAlbum.fromJson(json))
        .toList();

  } else {
    throw Exception('Failed!');
  }
}
lb3vh1jj

lb3vh1jj1#

为共享首选项创建类

class SharedPrefrence {
  Future<bool> setToken(String token) async {
    final SharedPreferences prefs = await SharedPreferences.getInstance();
    return prefs.setString("token", token);
  }

  Future<String> getToken() async {
    final SharedPreferences prefs = await SharedPreferences.getInstance();
    return prefs.getString("token") ?? '';
  }
}

从API保存令牌数据

extract api response and pass to setToken function

 Map<String, dynamic> value = json.decode(response.body);

 SharedPrefrence().setToken(value['token']);

要从另一个页面或函数访问令牌,请按如下所示使用:您可以将变量创建为全局变量,并在initState中调用getToken函数,然后将令牌变量用于API或者在api代码中使用Future代码

String token;
@override
  void initState() {
    super.initState();

    Future auth_token = SharedPrefrence().getToken();
    auth_token.then((data) async {
      token = data;
      
    });
  }

在API代码中使用

Future<List<ListAlbum>> listData() async {
final token;
   Future auth_token = SharedPrefrence().getToken();
    auth_token.then((data) async {
      token = data;
      String url =
      'https://portal-api.jomakhata.com/api/getOrganizationData?token=${token}';

  Dio dio = new Dio();
  dio.options.headers['Content-Type'] = 'application/json';
  final body = {'limit': 100, 'orderBy': 'idEmployee', 'orderType': 'DESC'};
  final response = await dio.post(url, data: body);

  if (response.statusCode == 200) {
    print(response.statusCode);
    print(response.data);
    // sharedPreferences.setString("token", response.data['token']);

    return response.data["data"]["data"]
        .map<ListAlbum>((json) => ListAlbum.fromJson(json))
        .toList();

  } else {
    throw Exception('Failed!');
  }
    });
  
}
ig9co6j1

ig9co6j12#

sharedPreferences.setString()sharedPreferences.setInt()是Futures。因为您没有使用await,所以函数正在执行,但您没有等待它完成。
请尝试以下操作:

await sharedPreferences.setString("token", data['token']);
await sharedPreferences.setInt("userId", data['userId']);

相关问题