Skip to content

Boring206/food_app

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

20 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🍽️ MealAI - 智能食物辨識與營養追蹤 App

使用 React Native (Expo)Node.js/Express 建置的 AI 驅動食物辨識與熱量估算系統。透過 Gemini Vision API 自動識別食物、計算營養素,並提供個人化飲食建議。

React Native Expo Node.js


✨ 主要功能

  • 📸 智能食物辨識 - 拍照或上傳圖片,AI 自動識別食物並計算熱量
  • 📊 營養分析 - 詳細的蛋白質、碳水、脂肪、纖維等營養素分析
  • 🎯 個人化目標 - 根據身高、體重、性別生成每日飲食目標
  • 📈 歷史追蹤 - 記錄並分析飲食歷史,提供趨勢圖表
  • 💾 雲端同步 - 使用 Supabase 儲存資料,支援多裝置同步
  • 🎨 現代化 UI - 精美的視覺設計,直觀的使用體驗

📋 目錄


🔧 系統需求

  • 作業系統: Windows 10/11, macOS, 或 Linux
  • Node.js: 18.0.0 或更高版本
  • npmyarn
  • Expo CLI (隨 npm install 自動安裝)
  • Supabase 帳號 (用於資料儲存)
  • Google Gemini API Key (用於 AI 辨識)

可選工具

  • ngrok - 用於對外測試 (非必需)
  • 夜神模擬器 或其他 Android/iOS 模擬器

📁 專案結構

food_app/
├── foodidentify/              # React Native (Expo) 前端
│   ├── App.js                 # 應用程式入口
│   ├── app.json               # Expo 配置
│   ├── app.config.js          # 動態配置(含環境變數)
│   ├── package.json
│   ├── .env                   # 環境變數(需自行建立)
│   ├── src/
│   │   ├── core/              # 核心功能
│   │   │   ├── AuthContext.js      # 認證管理
│   │   │   ├── MealContext.js      # 餐點管理
│   │   │   ├── AIService.js        # AI 服務整合
│   │   │   └── HistoryRepository.js # 歷史記錄管理
│   │   ├── screens/           # 頁面元件
│   │   │   ├── HomeScreen.js        # 首頁
│   │   │   ├── ScanLanding.js       # 掃餐頁面
│   │   │   ├── ResultScreen.js      # 結果頁面
│   │   │   ├── HistoryScreen.js      # 歷史記錄
│   │   │   └── AccountScreen.js      # 帳戶管理
│   │   ├── ui/                # UI 元件
│   │   │   ├── Card.js              # 卡片元件
│   │   │   └── NutrientBar.js       # 營養進度條
│   │   ├── navigation/        # 導航設定
│   │   └── lib/               # 工具庫
│   │       └── supabase.js    # Supabase 客戶端
│   └── assets/                # 圖片與字型
│
└── foodidentify-server/       # Node.js 後端
    ├── server.js              # Express 伺服器
    ├── package.json
    ├── .env                   # 環境變數(需自行建立)
    └── uploads/               # 圖片暫存目錄

🚀 快速開始

1. 克隆專案

git clone <your-repo-url>
cd food_app

2. 安裝依賴

# 後端
cd foodidentify-server
npm install

# 前端
cd ../foodidentify
npm install

💡 提示: npm install 會自動安裝所有必要的套件,詳見下方 套件列表 章節。

3. 設定環境變數

詳見 環境設定 章節。

4. 啟動服務

# 終端 1: 啟動後端
cd foodidentify-server
npm start

# 終端 2: 啟動前端
cd foodidentify
npm start

📦 套件列表

後端套件 (foodidentify-server)

執行 npm install 會自動安裝以下套件:

核心框架:

  • express ^4.21.2 - Web 框架
  • cors ^2.8.5 - 跨域資源共享
  • dotenv ^16.6.1 - 環境變數管理

AI 與圖像處理:

  • @google/generative-ai ^0.21.0 - Google Gemini API
  • sharp ^0.34.5 - 高性能圖像處理
  • jimp ^0.22.12 - JavaScript 圖像處理庫
  • @tensorflow/tfjs ^4.22.0 - TensorFlow.js

檔案處理:

  • multer ^1.4.5-lts.2 - 檔案上傳中間件
  • node-fetch ^3.3.2 - HTTP 請求(跨平台 fetch)

工具:

  • uuid ^13.0.0 - UUID 生成器

前端套件 (foodidentify)

執行 npm install 會自動安裝以下套件:

核心框架:

  • expo ~54.0.25 - Expo SDK
  • react 19.1.0 - React 核心
  • react-dom 19.1.0 - React DOM
  • react-native 0.81.5 - React Native 核心

導航:

  • @react-navigation/native ^7.1.19 - React Navigation 核心
  • @react-navigation/native-stack ^7.6.2 - Stack 導航
  • @react-navigation/drawer ^7.7.2 - Drawer 導航
  • react-native-screens ~4.16.0 - 原生螢幕管理
  • react-native-safe-area-context ^5.6.2 - 安全區域處理
  • react-native-gesture-handler 2.16.2 - 手勢處理
  • react-native-reanimated ^4.1.3 - 動畫庫

Expo 模組:

  • expo-image-picker ~17.0.8 - 圖片選擇器
  • expo-file-system ~19.0.19 - 檔案系統
  • expo-sharing ^14.0.7 - 分享功能
  • expo-print ~14.0.1 - PDF 列印
  • expo-status-bar ~3.0.8 - 狀態列

資料管理:

  • @supabase/supabase-js ^2.83.0 - Supabase 客戶端
  • @react-native-async-storage/async-storage ^2.2.0 - 本地儲存

圖表與視覺化:

  • react-native-chart-kit ^6.12.0 - 圖表庫(BarChart, LineChart)
  • react-native-svg 15.12.1 - SVG 支援

UI 元件:

  • @react-native-picker/picker 2.11.1 - 選擇器元件
  • react-native-view-shot ^4.0.3 - 視圖截圖
  • @expo/vector-icons - 圖標庫(MaterialCommunityIcons, Ionicons 等,隨 Expo SDK 自動包含)

網路與工具:

  • axios ^1.12.2 - HTTP 客戶端
  • react-native-url-polyfill ^3.0.0 - URL Polyfill
  • react-native-get-random-values ^2.0.0 - 隨機值生成
  • react-native-web ^0.21.0 - Web 支援
  • react-native-worklets 0.5.1 - Worklets 支援

加密與工具:

  • bcryptjs ^3.0.3 - 密碼雜湊
  • crypto-js ^4.2.0 - 加密工具
  • uuid ^13.0.0 - UUID 生成器
  • dotenv ^16.4.5 - 環境變數管理

開發工具 (devDependencies):

  • @types/react ~19.1.10 - React TypeScript 類型
  • typescript ~5.9.2 - TypeScript 編譯器

💡 提示: 所有套件會透過 npm install 自動安裝,無需手動下載。版本號前的 ^~ 表示允許安裝兼容的更新版本。


⚙️ 環境設定

前端環境變數 (foodidentify/.env)

建立 .env 檔案:

SUPABASE_URL=https://your-project.supabase.co
SUPABASE_ANON_KEY=your_anon_key

💡 提示: 這些變數會在打包時自動注入到 app.config.js,不會暴露在程式碼中。

後端環境變數 (foodidentify-server/.env)

建立 .env 檔案:

PORT=3000
GEMINI_API_KEY=your_gemini_api_key
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_SERVICE_ROLE=your_service_role_key
ALLOWED_ORIGINS=*

取得 API 金鑰

  1. Supabase:

    • 前往 Supabase Dashboard
    • 建立新專案或選擇現有專案
    • 在 Settings > API 中取得 URL 和 Keys
  2. Google Gemini API:


🎯 啟動指南

啟動後端伺服器

cd foodidentify-server
npm start

伺服器將在 http://localhost:3000 啟動。

啟動前端應用

方法 1: LAN 模式(推薦 - 同 WiFi 網路)

cd foodidentify
npm start
#
npm run lan

方法 2: Tunnel 模式(跨網路)

npm run tunnel

方法 3: 本地模式(僅本機)

npm run localhost

連接設備

  • 實體手機: 使用 Expo Go 掃描 QR Code
  • Android 模擬器: 自動連接(使用 10.0.2.2:3000
  • iOS 模擬器: 自動連接(使用 localhost:3000
  • Web: 按 w 鍵在瀏覽器中開啟

🍱 功能說明

1. 帳戶管理

  • 註冊/登入: 使用 Email 和密碼註冊帳號
  • 個人資料: 設定身高、體重、性別(用於個人化建議)
  • 資料同步: 所有資料儲存在 Supabase,支援多裝置同步

2. 食物辨識

  1. 進入「掃餐」頁面
  2. 選擇「拍照」或「從相簿選擇」
  3. 可選填備註(如:午餐、外食等)
  4. 點擊「送到 AI 估算」
  5. 查看辨識結果與營養分析

3. 結果查看

  • 食物名稱: AI 識別的食物名稱
  • 熱量: 總熱量(大卡)
  • 營養素: 蛋白質、碳水、脂肪、纖維、糖、鈉
  • 信心度: AI 辨識的信心百分比
  • AI 建議: 營養師建議

4. 歷史記錄

  • 查看所有已儲存的餐點
  • 點擊查看詳細資訊
  • 支援編輯、刪除、分享功能
  • 自動計算每日/每週營養總和

5. 個人化目標

  1. 在首頁輸入今日需求(如:減脂、增肌、外食較多)
  2. 點擊「生成個人化目標」
  3. AI 根據你的資料生成:
    • 每日熱量目標
    • 營養素分配(蛋白質、碳水、脂肪)
    • 餐次建議

6. 營養圖表

  • 7 天趨勢: 查看近一週的營養攝取
  • 30 天趨勢: 查看近一個月的營養攝取
  • PDF 匯出: 匯出包含個人資料的營養報表

🌐 API 文檔

後端端點

POST /predict

分析食物圖片並回傳營養資訊。

請求格式: multipart/form-data

參數:

  • image (File, 必填): 食物圖片
  • note (String, 選填): 使用者備註

回應範例:

{
  "success": true,
  "prediction": {
    "food": "漢堡",
    "calories": 500,
    "macros": {
      "protein": 20,
      "carbs": 30,
      "fat": 25,
      "fiber": 3,
      "sugar": 5,
      "sodium_mg": 800
    },
    "confidence": 0.85,
    "advice": ["建議搭配蔬菜", "注意鈉含量"]
  },
  "mode": "gemini-vision"
}

POST /goals

生成個人化飲食目標。

請求格式: application/json

參數:

{
  "heightCm": 180,
  "weightKg": 70,
  "gender": "male",
  "preference": "減脂"
}

回應範例:

{
  "success": true,
  "goals": {
    "calories": 2000,
    "macros": {
      "protein": 150,
      "carbs": 200,
      "fat": 65
    },
    "meals": [
      {
        "meal": "早餐",
        "suggestion": "燕麥片配水果"
      }
    ]
  }
}

GET /health

檢查伺服器狀態。

回應:

{
  "status": "ok",
  "timestamp": "2025-12-09T15:00:00.000Z",
  "gemini": true
}

🔧 故障排除

問題 1: 無法連接到後端伺服器

Android 模擬器:

  • 確保使用 10.0.2.2:3000(已在程式碼中自動設定)
  • 檢查後端伺服器是否正在運行

實體手機:

  • 確保手機和電腦在同一 WiFi 網路
  • 使用 LAN 模式啟動 Expo
  • 檢查防火牆設定

解決方法:

# 檢查伺服器是否運行
curl http://localhost:3000/health

# 檢查 IP 地址
ipconfig  # Windows
ifconfig  # macOS/Linux

問題 2: Supabase 連接失敗

錯誤: Supabase 設定缺失

解決方法:

  1. 確認 .env 檔案存在於 foodidentify/ 目錄
  2. 確認變數名稱正確:SUPABASE_URLSUPABASE_ANON_KEY
  3. 重新啟動 Expo 伺服器

問題 3: Gemini API 配額超限

錯誤: 429 Too Many Requests

解決方法:

  1. 檢查 Google AI Studio 的配額設定
  2. 等待配額重置(通常每分鐘/每天)
  3. 考慮升級到付費方案

問題 4: 登入/註冊失敗

錯誤: permission deniedRLS policy violation

解決方法:

  1. 前往 Supabase Dashboard
  2. 進入 SQL Editor
  3. 執行以下 SQL(僅用於開發環境):
ALTER TABLE profiles DISABLE ROW LEVEL SECURITY;

⚠️ 警告: 關閉 RLS 僅適用於開發環境,生產環境請設定正確的 RLS 策略。

問題 5: Expo 連接問題

錯誤: 無法掃描 QR Code 或連接失敗

解決方法:

# 清除快取並重新啟動
npx expo start -c

# 或使用 LAN 模式
npm run lan

💻 開發指南

開發模式

# 前端開發模式(自動重新載入)
cd foodidentify
npm start

# 後端開發模式(需要手動重啟)
cd foodidentify-server
npm start

程式碼結構

  • Context: 使用 React Context 管理全域狀態

    • AuthContext: 使用者認證與個人資料
    • MealContext: 餐點分析與歷史記錄
    • ThemeContext: 主題切換(亮色/暗色)
  • 服務層:

    • AIService: 處理與後端的通訊
    • HistoryRepository: 管理歷史記錄的 CRUD 操作
  • UI 元件:

    • Card: 統一的卡片樣式
    • NutrientBar: 營養進度條
    • MacroPill: 營養素標籤

新增功能

  1. src/screens/ 建立新頁面
  2. src/navigation/RootDrawer.js 註冊路由
  3. 如需新 API,在 AIService.js 新增方法
  4. 如需新 UI 元件,在 src/ui/ 建立

📝 技術棧

前端

  • React Native 0.81.5
  • Expo 54.0.25
  • React Navigation 7.x
  • Supabase JS 2.83.0
  • Axios 1.12.2

後端

  • Node.js 18+
  • Express 4.x
  • Google Gemini API (Vision)
  • Multer (檔案上傳)

資料庫

  • Supabase (PostgreSQL)

🤝 貢獻

歡迎提交 Issue 或 Pull Request!

提交 Issue

請包含:

  • 問題描述
  • 重現步驟
  • 預期行為 vs 實際行為
  • 環境資訊(OS, Node 版本等)

提交 Pull Request

  1. Fork 專案
  2. 建立功能分支 (git checkout -b feature/AmazingFeature)
  3. 提交變更 (git commit -m 'Add some AmazingFeature')
  4. 推送到分支 (git push origin feature/AmazingFeature)
  5. 開啟 Pull Request

📄 授權

本專案採用 MIT 授權。


🙏 致謝


📞 聯絡方式

如有問題或建議,請透過以下方式聯絡:


Made with ❤️ using React Native & Expo

About

食物辨識與熱量估算系統

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors