A mini BeReal replacement (without any social features) that uploads a photo-a-day to Notion.
- 📸 Take daily photos with front or back camera
- 📝 Add captions to your photos
- 🗂️ Automatically upload to Notion database
- 📅 Daily notification reminders (at random times between 9 AM - 9 PM)
- 🎲 Notification time changes automatically after each photo (keeps it unpredictable!)
- 🔒 Secure OAuth authentication
- Node.js (version specified in
.nvmrc) - Expo CLI
- A Notion account
- A Vercel account (for hosting the OAuth backend)
- Go to https://www.notion.so/my-integrations
- Click "New integration"
- Set the integration type to "Public" (important!)
- Give it a name (e.g., "Daily Photo")
- Select capabilities:
- Read content
- Update content
- Insert content
- Click "Submit"
- Save your OAuth client ID and OAuth client secret (you'll need these later)
- In Notion, create a new database (table view works well)
- Add these properties:
- Caption (Title) - for the photo caption
- Photo (Files & media) - for the photo
- Copy the database ID from the URL:
- URL format:
https://www.notion.so/workspace/DATABASE_ID?v=... - Save the
DATABASE_IDfor later
- URL format:
The backend handles OAuth token exchange securely (keeping your client secret safe).
-
Install Vercel CLI (if not already installed):
npm install -g vercel
-
Deploy the backend:
vercel
-
Follow the prompts:
- Set up and deploy? Yes
- Which scope? Choose your account
- Link to existing project? No
- Project name? Use default or choose your own
- Directory?
.(current directory) - Override settings? No
-
After deployment, Vercel will give you a URL like:
https://your-project.vercel.app -
Set environment variables in Vercel:
vercel env add NOTION_CLIENT_ID vercel env add NOTION_CLIENT_SECRET vercel env add NOTION_REDIRECT_URI
Or via the Vercel dashboard:
- Go to your project settings → Environment Variables
- Add:
NOTION_CLIENT_ID: Your Notion OAuth client IDNOTION_CLIENT_SECRET: Your Notion OAuth client secretNOTION_REDIRECT_URI:https://your-project.vercel.app/api/notion-callback
-
Redeploy to apply environment variables:
vercel --prod
- Go back to https://www.notion.so/my-integrations
- Select your integration
- Under "Redirect URIs", add:
https://your-project.vercel.app/api/notion-callback - Save changes
-
Create a
.envfile in the project root:cp .env.example .env
-
Edit
.envand add:EXPO_PUBLIC_NOTION_CLIENT_ID=your_notion_client_id EXPO_PUBLIC_BACKEND_URL=https://your-project.vercel.app -
Install dependencies:
npm install
After authenticating via OAuth:
- Open your Notion database
- Click "..." menu → "Connections"
- Search for your integration name
- Click to connect
npm startThis will start the Expo development server with tunnel mode enabled.
npm run android # Run on Android
npm run ios # Run on iOS
npm run web # Run on webYou can test the Notion upload functionality without running the mobile app:
npm run test-uploadThis script uploads a test image from images/bereal.png to your Notion database.
daily-photo/
├── api/ # Vercel serverless functions
│ └── notion-callback.ts # OAuth callback handler
├── app/ # Expo Router screens
│ ├── _layout.tsx # Root layout with auth
│ ├── index.tsx # Camera screen
│ ├── login.tsx # OAuth login screen
│ ├── settings.tsx # Settings & logout
│ └── oauth/
│ └── callback.tsx # OAuth redirect handler
├── lib/ # Core business logic
│ ├── notion.ts # Notion API integration
│ ├── notionAuth.ts # OAuth hook
│ ├── notifications.ts # Daily notifications
│ └── storage.ts # SecureStore helpers
├── constants/
│ └── config.ts # App configuration
└── scripts/
└── uploadToNotion.ts # CLI upload utility
- User taps "Connect to Notion" in the app
- App opens browser to Notion OAuth page (redirects to backend URL)
- User authorizes the app and selects which pages to share
- Notion redirects to the backend with an authorization code
- Backend exchanges the code for access/refresh tokens (keeps client secret secure)
- Backend redirects to the app via deep link (
dailynotion://oauth/callback) with tokens - App stores tokens securely in device's secure storage
- App uses tokens for all Notion API requests
- Never commit
.envfiles to git - Never expose your
NOTION_CLIENT_SECRETin the mobile app - All OAuth token exchanges happen on the backend
- Tokens are stored in device's secure encrypted storage (
expo-secure-store) - The hardcoded token from the initial version has been removed
- Make sure you've completed the OAuth flow
- Try logging out and logging back in
- Check that environment variables are set correctly
- Check Vercel logs:
vercel logs - Verify environment variables are set in Vercel dashboard
- Ensure redirect URI matches exactly in Notion integration settings
- Make sure
scheme: "dailynotion"is inapp.json - Rebuild the app after changing
app.json - Check that deep link format matches:
dailynotion://oauth/callback
Private project