質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
86.12%
Flutter

Flutterは、iOSとAndroidのアプリを同じコードで開発するためのフレームワークです。オープンソースで開発言語はDart。双方のプラットフォームにおける高度な実行パフォーマンスと開発効率を提供することを目的としています。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

解決済

FlutterからAPI(PHP)へ、リモートデータ通信ができない

Y.Mamoru
Y.Mamoru

総合スコア47

Flutter

Flutterは、iOSとAndroidのアプリを同じコードで開発するためのフレームワークです。オープンソースで開発言語はDart。双方のプラットフォームにおける高度な実行パフォーマンスと開発効率を提供することを目的としています。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

1回答

0リアクション

0クリップ

247閲覧

投稿2022/10/03 10:41

編集2022/10/04 02:08

前提

Flutterアプリの画面で入力した内容を、
PHPで作成したAPIにリモートで飛ばすのですが
値を飛ばすことができません。

実現したいこと

Flutterの画面から入力した値をPHPで作成したAPIに送信する、ログイン機能を作成しようとしてます。

発生している問題・エラーメッセージ

Flutter側の送信でエラーが起こっているようです。

dart

XMLHttpRequest error. No ScaffoldMessenger widget found. Login widgets require a ScaffoldMessenger widget ancestor. The specific widget that could not find a ScaffoldMessenger ancestor was: Login The ancestors of this widget were: [root] Typically, the ScaffoldMessenger widget is introduced by the MaterialApp at the top of your application widget tree.

該当のソースコード

dart

//ログイン処理 Future<void> _login() async { if (!_formKey.currentState!.validate()) { return; } setState(() { _isLoading = true; }); //dataに値が入っていることは確認できています Map<String, String> data = {'email': _mail!, 'password': _password!}; Response? res; try { //このPOST処理に入ったときにエラーが発生します。 res = await Network().postData(data, '/ReadUserInfo'); } catch (e) { // debugPrint(e.toString()); print("エラー内容:"+e.toString()); } if (res == null) { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text("エラーが発生しました。")), ); } setState(() { _isLoading = false; }); return; } var body = json.decode(res.body); // エラーの場合 if (res.statusCode != 200) { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(body['message'])), ); } setState(() { _isLoading = false; }); return; } // 正常終了の場合 SharedPreferences localStorage = await SharedPreferences.getInstance(); localStorage.setString('token', json.encode(body['token'])); localStorage.setString('user', json.encode(body['user'])); if (!mounted) return; Navigator.push( context, MaterialPageRoute(builder: (context) => const TabPage()), ); } //以下ログイン画面生成処理 Widget build(BuildContext context) { return MaterialApp( home:Scaffold( appBar: AppBar( centerTitle: true, title: const Text("ログイン"), ), body: SafeArea( child: _isLoading ? const Center( child: CircularProgressIndicator(), ) : Form( key: _formKey, child: Container( padding: const EdgeInsets.all(16), child: Column( children: [ TextFormField( keyboardType: TextInputType.emailAddress, decoration: const InputDecoration( hintText: "メールアドレス", ), validator: (emailValue) { if (emailValue == null || emailValue == "") { return 'メールアドレスは必ず入力してください。'; } _mail = emailValue; return null; }, ), TextFormField( keyboardType: TextInputType.visiblePassword, obscureText: isHiddenPassword, decoration: InputDecoration( hintText: "パスワード", suffixIcon: IconButton( icon: Icon(isHiddenPassword ? Icons.remove_red_eye : Icons.visibility_off), onPressed: () { setState(() { isHiddenPassword =!isHiddenPassword; }); }), ), validator: (passwordValue) { if (passwordValue == null || passwordValue == "") { return 'パスワードは必ず入力してください。'; } _password = passwordValue; return null; }, ), const SizedBox( height: 32, ), ElevatedButton( onPressed: () { _login(); }, child: const Text("ログイン")), const SizedBox( height: 16, ), ElevatedButton( onPressed: () { runApp(const SignUpPage() ); }, child: const Text("会員登録")), const SizedBox( height: 16, ), ], ), ))))); }

dart

//APIへ接続するクラスです import 'dart:convert'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:http/http.dart'; class Network { // Androidシュミレーターを使う場合はlocalhostを10.0.2.2に変更する //ここでPHP側のURLを指定(こちらのURLが正しいことは確認済みです。直接叩いて特定のファイルまで飛ぶことができます) final String _url = 'https://XXX.XXX.XXX.XX/index.php'; String? token; // SharedPreferences(データを保存する仕組み)からトークンを取得 _setToken() async { SharedPreferences localStorage = await SharedPreferences.getInstance(); String? localToken = localStorage.getString('token'); // なぜかlocalStorageから取得した値の前後に"が入るので仕方なくここで置換する if (localToken != null) { token = localToken.replaceAll('"', ''); } } // ヘッダー情報をセット _getHeaders() => { 'Content-type': 'application/json', 'Accept': 'application/json', 'Authorization': 'Bearer $token' }; // POST //ここのapiUrlで、PHP側のログインAPIを指定(/login など) Future<Response> postData(data, String apiUrl) async { await _setToken(); Uri fullUrl = Uri.parse(_url + apiUrl); //この時点でfullUrlとdataの中身が正しいことは確認済みです return await post(fullUrl, body: jsonEncode(data), headers: _getHeaders()); } // GET Future<Response> getData(String apiUrl) async { await _setToken(); Uri fullUrl = Uri.parse(_url + apiUrl); Response res = await get(fullUrl, headers: _getHeaders()); return res; } }

試したこと

・作成するにあたって参考にしているサイトはこちらです。
https://qiita.com/atm_33/items/9ffc89caf1c2b6d6d661

・デバッグで確認したところ入力した内容は変数に格納されています。
(_mailと_passwordです)

・postDataメソッドを実行した後にエラーが発生します

・「XMLHttpRequest error.No ScaffoldMessenger widget found.」
をキーワードで検索した結果、同様の現象について書かれた記事があったので書かれている通りグローバルキーを作ってみましたが、結果は変わりませんでした。
https://stackoverflow.com/questions/66833689/flutter-no-scaffoldmessenger-widget-found

・デバッグで確認すると、API接続ファイルの方で作成しているlocal tokenがnullであることがわかりました。
これが原因かと思い、local tokenの作成方法を調べていますが、
すでに実装コードは書いているので、なぜnullなのかもわかっていない状態です。

追記です。
tokenがnullであることは、もしかしたら問題ないかもしれません。
定義の段階でtokenはnull許容であることと、
ここでのtokenはAPIから受け取る際に使われると参考サイトに書かれていたことから判断しました。

補足情報(FW/ツールのバージョンなど)

開発ツール:AndroidStudio4.01
DartSDKバージョン:2.17.6
Flutterバージョン:3.05

以下のような質問にはリアクションをつけましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

リアクションが多い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

Y.Mamoru

2022/10/03 10:54

前回はPHP側の受け取り方を教えていただき、ローカル上でそれはできたのですが 今回は別で作成されたAPIにリモートで接続させる流れになっています。 前回と同様にしてみたのですが、 できなかったので再度質問として挙げさせていただきました
m.ts10806

2022/10/03 10:57

そのリモート先は、例えばローカルからブラウザでURLそのまま実行してちゃんとアクセスは出来てるんでしょうか。 ポート開放など適切な設定はされていますか?
m.ts10806

2022/10/03 10:58 編集

えっと、タイトル紛らわしいのでリモート先であることはタイトルと本文にも明記しておいてもらえると。コードまで全部読まないと分からないのは説明不足で伝わらないと思いますので。
Y.Mamoru

2022/10/03 11:07

ブラウザからリモート先へのアクセスはできています。 ポートの開放もできている状態です。 すみません、タイトルと本文を修正します

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
86.12%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

Flutter

Flutterは、iOSとAndroidのアプリを同じコードで開発するためのフレームワークです。オープンソースで開発言語はDart。双方のプラットフォームにおける高度な実行パフォーマンスと開発効率を提供することを目的としています。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。