A full-stack notes application with file attachments, built with Flutter (frontend) and Node.js/Express (backend) with SQLite storage. Includes push notifications via Firebase Cloud Messaging and local notifications.
| Layer | Technology |
|---|---|
| Frontend | Flutter 3.x, Dart |
| Backend | Node.js, Express 5 |
| Database | SQLite via Sequelize ORM |
| File Uploads | Multer (local disk storage) |
| Notifications | Flutter Local Notifications, Firebase Cloud Messaging |
| Theming | Material 3 with light/dark mode |
- CRUD Operations — Create, read, update, and delete notes
- File Attachments — Upload JPG, PNG, or PDF files (max 10 MB) to notes
- Dark/Light Theme — Toggle between themes with persistence across sessions
- Pull to Refresh — Swipe down to refresh the note list
- Local Notifications — Notification on note creation
- Push Notifications — FCM setup for foreground, background, and cold start messages
- Multi-platform — Android, iOS, Web, macOS, Windows support
note-app/
├── backend/
│ ├── config/
│ │ └── database.js # Sequelize + SQLite config
│ ├── models/
│ │ └── Note.js # Note model (title, description, file_url)
│ ├── routes/
│ │ ├── notes.js # Notes CRUD endpoints
│ │ └── upload.js # File upload endpoint
│ ├── uploads/ # Uploaded files directory
│ ├── .env # Environment variables
│ ├── index.js # Express app entry point
│ ├── package.json
│ └── database.sqlite # SQLite database file
├── frontend/
│ ├── lib/
│ │ ├── main.dart # App entry, theme, Firebase init
│ │ ├── notification.dart # Local + FCM notification setup
│ │ ├── firebase_options.dart # Firebase config (FlutterFire CLI)
│ │ ├── screens/
│ │ │ ├── note_list_screen.dart # Note list with search, refresh, delete
│ │ │ └── note_form_screen.dart # Create/edit form with file upload
│ │ └── services/
│ │ └── api_service.dart # HTTP client for backend API
│ ├── android/
│ ├── ios/
│ ├── web/
│ └── pubspec.yaml
└── README.md
- Node.js >= 18
- Flutter SDK >= 3.10
- Android Studio or VS Code with Flutter/Dart plugins
- For iOS: Xcode + CocoaPods
- For Firebase: A Firebase project with Cloud Messaging enabled
cd backend
npm installCreate a .env file in backend/:
PORT=3000
NODE_ENV=development
Start the server:
# Development (with auto-reload)
npm run dev
# Production
npm startThe API starts at http://localhost:3000. The SQLite database is auto-created on first run.
cd frontend
flutter pub getUpdate the API base URL in lib/services/api_service.dart to match your machine's IP:
static String get baseUrl {
if (kIsWeb) return 'http://localhost:3000';
// Replace with your local IP for native builds
return 'http://<YOUR_IP>:3000';
}Run the app:
flutter run| Method | Endpoint | Description | Body |
|---|---|---|---|
GET |
/notes |
List all notes | — |
GET |
/notes/:id |
Get a single note | — |
POST |
/notes |
Create a note | { title, description?, file_url? } |
PUT |
/notes/:id |
Update a note | { title, description?, file_url? } |
DELETE |
/notes/:id |
Delete a note | — |
| Method | Endpoint | Description | Body |
|---|---|---|---|
POST |
/upload |
Upload a file | multipart/form-data with file field |
Upload response:
{ "file_url": "http://localhost:3000/uploads/1724812345678-photo.jpg" }Upload limits: 10 MB max. All file types accepted.
| Method | Endpoint | Description |
|---|---|---|
GET |
/ |
Returns { status: "Notes API running", version: "1.0.0" } |
{
"id": 1,
"title": "My Note",
"description": "Optional description text",
"file_url": "http://localhost:3000/uploads/file.jpg",
"createdAt": "2025-01-01T00:00:00.000Z",
"updatedAt": "2025-01-01T00:00:00.000Z"
}| Field | Type | Required | Description |
|---|---|---|---|
id |
INTEGER | auto | Primary key |
title |
STRING | yes | Note title |
description |
TEXT | no | Note body |
file_url |
STRING | no | URL to uploaded file |
createdAt |
DATE | auto | Creation timestamp |
updatedAt |
DATE | auto | Last update timestamp |
The app includes Firebase Cloud Messaging integration. To enable it:
- Create a Firebase project at console.firebase.google.com
- Install FlutterFire CLI:
dart pub global activate flutterfire_cli - Run
flutterfire configurefrom thefrontend/directory - This will update
lib/firebase_options.dartand platform configs
For Android: Ensure google-services.json is in android/app/.
For iOS: Ensure GoogleService-Info.plist is in ios/Runner/ and APNs is configured in Firebase Console.