User Profile Update Code
August 8, 2025 · AI Conversations
<script>
import { ref,computed,onMounted,inject,watchEffect } from 'vue'
import {useDisplay} from 'vuetify'
import { useUserStore } from '@/stores/userStores'
import {getUserInfo,updateProfileData,updateUserPassword} from '@/dbstore/firebase/userService'
import {useLoadingStore} from '@/stores/loading'
import SnackBar from '@/components/SnackBar.vue'
const loadingStore = useLoadingStore()
const userStore = useUserStore()
const tab = ref('option-1')
const {mdAndUp} = useDisplay()
console.log(mdAndUp)
const tabDirection = computed(() => mdAndUp.value ? 'vertical' : 'horizontal')
const containerDirection = computed(() => mdAndUp.value ? 'flex-row' : 'flex-column')
const userInfo = ref(null)
const profileForm = ref(null)
const passwordForm = ref(null)
const password = ref('');
const confirmPassword = ref('');
const error = ref(null)
const requiredRule = [(v) => !!v || 'This field is required']
const passwordRules = ref([(v) => !!v || 'Password is required', (v) => (v && v.length >= 6) || 'Password must be at least 6 characters'])
const confirmPasswordRules = ref([(v) => !!v || 'Confirm Password is required', (v) => (v && v.length >= 6 && v === password.value) || 'Confirm Password must be at least 6 characters'])
const showNetworkSnackbar = ref(false);
const snackbarText = ref('');
const snackbarColor = ref('danger');
// inject returns `unknown`, so we type it as a string array
const userCategories = inject('userCategories', [])
const fetchUserInfo = async () => {
loadingStore.setLoading(true)
try {
const user = await getUserInfo(userStore.currentUser.uid)
userInfo.value = user
console.log(userInfo);
} catch (err) {
error.value = err
} finally {
loadingStore.setLoading(false)
}
}
const updateProfile = async () => {
const {valid} = await profileForm.value.validate()
if (!valid) return
loadingStore.setLoading(true)
try {
await updateProfileData(userStore.currentUser, userInfo.value)
snackbarText.value = 'Profile updated successfully!'
snackbarColor.value = 'success'
} catch (err) {
error.value = err
snackbarText.value = err.message
snackbarColor.value = 'danger'
} finally {
showNetworkSnackbar.value = true;
loadingStore.setLoading(false)
}
}
const updatePassword = async () => {
const {valid} = await passwordForm.value.validate()
if (!valid) return
loadingStore.setLoading(true)
console.log(password.value,confirmPassword.value);
try {
await updateUserPassword(userStore.currentUser, password.value)
snackbarText.value = 'Password updated successfully!'
snackbarColor.value = 'success'
} catch (err) {
console.log(err)
snackbarText.value = err.message
snackbarColor.value = 'danger'
} finally {
passwordForm.value.reset()
showNetworkSnackbar.value = true;
loadingStore.setLoading(false)
}
}
onMounted(() => {
fetchUserInfo()
})
</script>
Update
Update
Fusce a quam. Phasellus nec sem in justo pellentesque facilisis. Nam eget dui. Proin viverra, ligula sit amet ultrices semper, ligula arcu tristique sapien, a accumsan nisi mauris ac eros. In dui magna, posuere eget, vestibulum et, tempor auctor, justo.
Cras sagittis. Phasellus nec sem in justo pellentesque facilisis. Proin sapien ipsum, porta a, auctor quis, euismod ut, mi. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nam at tortor in tellus interdum sagittis.
on page referesh
onMounted(() => {
fetchUserInfo()
})
not showing any details
Like uid is missing on page refersh
### ✅ Solution: Wait for Firebase auth to initialize before calling `fetchUserInfo()`
Update your logic like this:
—
### Step 1: Modify `onMounted()` to wait until `userStore.currentUser` is available
onMounted(async () => {
const waitForUser = () =>
new Promise((resolve) => {
const interval = setInterval(() => {
if (userStore.currentUser && userStore.currentUser.uid) {
clearInterval(interval)
resolve(true)
}
}, 100)
})
await waitForUser()
fetchUserInfo()
})
—
### Step 2: (Optional but Recommended) Add `initAuth()` in your user store if not already added:
Your `userStore` should include this logic if it isn't already:
const initAuth = () => {
onAuthStateChanged(auth, (user) => {
currentUser.value = user
isLoggedIn.value = !!user
})
}
And call `userStore.initAuth()` in your main `App.vue` or `main.ts` before the app loads fully.
—
Let me know if you want this `waitForUser` logic abstracted into a composable!
import { createApp } from 'vue'
import vuetify from "@/plugins/vuetify"
import { createPinia } from 'pinia'
import App from './App.vue'
import router from './router'
import { API_URL } from '@/config'
import IconLoading from './components/IconLoading.vue'
import { useAdminStore } from './stores/adminStores'
import { useUserStore } from './stores/userStores'
import OverlayLoading from './components/OverlayLoading.vue'
const app = createApp(App)
app.use(createPinia())
useUserStore().initAuth()
useAdminStore().initAdminAuth()
app.use(vuetify)
app.use(router)
app.provide('userCategories', [
'Fullstack Developer',
'Frontend Developer',
'Backend Developer',
'Project Coordinator',
'Student',
'Learner'
])
app.component('IconLoading', IconLoading);
app.component('OverlayLoading', OverlayLoading);
app.provide('apiUrl', API_URL);
// ✅ Initialize both user and admin auth listeners
app.mount('#app')
still not worked
### ✅ **Recommended Fix: Add a `watch` to wait for currentUser**
Update your `onMounted` + add a `watch` in your “:
onMounted(() => {
// If currentUser is already available, fetch immediately
if (userStore.currentUser?.uid) {
fetchUserInfo()
}
// Otherwise, watch until it becomes available
watch(
() => userStore.currentUser,
(val) => {
if (val?.uid) {
fetchUserInfo()
}
},
{ immediate: false }
)
})
—
### 💡 Why this works:
`onMounted()` runs **before** Firebase finishes restoring the session. So we:
– check immediately (`if (userStore.currentUser?.uid)`) in case it's already there.
– watch `userStore.currentUser` and trigger `fetchUserInfo()` once it becomes available.
—
Let me know if you want to debounce or cleanup this `watch` further, or convert it into a reusable composable.
Mix content error firebase hosting and http aws
How we can use it
### 🔐 Why This Is Blocked:
Browsers **block** all insecure (`http://`) API calls from secure (`https://`) websites for security reasons.
—
## ✅ Fix: Serve Your AWS API Over HTTPS
You **must** enable HTTPS on your EC2 instance. Here are your options:
—
### 🔧 Option 1: **Use a Free SSL Certificate via Let's Encrypt**
If your EC2 server uses **Apache** or **Nginx**, the easiest path is using [Certbot](https://certbot.eff.org/) (Let's Encrypt):
#### Example for Ubuntu + Apache:
sudo apt update
sudo apt install certbot python3-certbot-apache
sudo certbot --apache
#### For Nginx:
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx
—
### 🛡️ Option 2: **Use a Load Balancer or Cloudflare (for SSL termination)**
– Point your domain to EC2 using **Cloudflare DNS**.
– Enable **“Flexible SSL” or “Full SSL”** in Cloudflare.
– Your frontend hits `https://api.yourdomain.com`, and Cloudflare handles HTTPS → HTTP internally if needed.
– Or better: install SSL on the EC2 and use **Full (Strict)** mode.
—
### 🌍 Option 3: Use AWS Certificate Manager (If
—
## 🔁 ✅ Workaround: Use a Secure **Proxy** on Firebase Hosting (or any HTTPS server)
You can create a **proxy endpoint** that runs on Firebase (or another HTTPS server), which securely forwards the request to your **HTTP EC2 API**.
—
### 🔧 Step-by-Step Setup with Firebase Functions
1. **Enable Firebase Cloud Functions** if not already:
firebase init functions
2. **Install `axios` inside `functions/` directory:**
cd functions
npm install axios
3. **Create the proxy function:**
In `functions/index.js` or `functions/index.ts`:
const functions = require('firebase-functions');
const axios = require('axios');
const cors = require('cors')({ origin: true });
exports.proxySendOtp = functions.https.onRequest((req, res) => {
cors(req, res, async () => {
try {
const response = await axios.post('http://YOUR_EC2_IP/api/send-otp', req.body, {
headers: { 'Content-Type': 'application/json' }
});
res.status(response.status).send(response.data);
} catch (err) {
res.status(500).send({ error: 'Proxy failed', details: err.message });
}
});
});
4. **Deploy the function:**
firebase deploy --only functions
5. **Use the HTTPS URL of your Cloud Function** in your app:
await fetch('https://your-project.cloudfunctions.net/proxySendOtp', {
method: 'POST',
body: JSON.stringify({ phone: '1234567890' }),
headers: { 'Content-Type': 'application/json' }
})
—
## 🔒 Why This Works
– Browser talks to Firebase (HTTPS ✅)
– Firebase Cloud Function securely forwards to EC2 (HTTP behind-the-scenes ✅)
– No browser mixed content issue ❌🚫
—
If you're already using Node.js or PHP on Firebase, I can help you write the proxy logic there too. Want that?
Vue.js alone **cannot solve this** because it's frontend-only and runs in the browser, which enforces security rules.
—
### ✅ Simplest Solution for You
**Use Firebase Cloud Functions** as a **secure HTTPS proxy** (no backend needed on AWS side). Here's the full plan customized for **Vue + Firebase Hosting**:
—
### 🔧 Step-by-Step (Full Walkthrough)
#### 1. **Set up Firebase Functions (if not already)**
firebase init functions
Choose:
– JavaScript
– ESLint? → your choice
– Install dependencies → Yes
—
#### 2. **Install Axios**
Inside the `functions` directory:
cd functions
npm install axios
—
#### 3. **Create a proxy in `functions/index.js`**
const functions = require('firebase-functions');
const axios = require('axios');
const cors = require('cors')({ origin: true });
exports.proxySendOtp = functions.https.onRequest((req, res) => {
cors(req, res, async () => {
try {
const response = await axios.post('http://your-ec2-ip/api/send-otp', req.body, {
headers: {
'Content-Type': 'application/json'
}
});
res.status(200).send(response.data);
} catch (error) {
res.status(500).send({ error: 'Proxy failed', message: error.message });
}
});
});
Replace `http://your-ec2-ip/api/send-otp` with your real API endpoint.
—
#### 4. **Deploy it**
firebase deploy --only functions
After deploy, you’ll get a URL like:
https://your-project.cloudfunctions.net/proxySendOtp
—
#### 5. **Use it in your Vue.js app:**
await fetch('https://your-project.cloudfunctions.net/proxySendOtp', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
phone: '1234567890',
// other data
})
})
.then(res => res.json())
.then(data => {
console.log(data)
})
.catch(err => {
console.error('Error:', err)
})
—
### ✅ Now:
– Your app is 100% HTTPS ✅
– EC2 API still works over HTTP ✅
– No Mixed Content errors ✅
Let me know if you'd like to set this up using **Netlify Functions** or **Vercel Serverless** instead — works just as well.
> 🔥 **You CANNOT create a true proxy using only `__redirects` in Firebase Hosting**.
—
### ❌ Why?
The [`__redirects`](https://firebase.google.com/docs/hosting/full-config#redirects) file (or `firebase.json` redirects) is **only for redirecting frontend routes** (like `/about` → `/index.html`). It cannot securely **bypass browser Mixed Content rules** or make server-side HTTP requests.
So:
https (browser) → http (EC2)
is still blocked. Even if you write this in `__redirects`:
/api/send-otp http://your-ec2-ip/api/send-otp 200
➡️ It **only causes the browser to try accessing `http://your-ec2-ip` directly**, which still triggers the **Mixed Content error**. Firebase Hosting doesn't proxy the request — it just rewrites the URL.
—
### ✅ The Only Secure Way via Firebase Hosting
You must use **Firebase Cloud Functions** or another backend service like:
– Netlify Functions
– Vercel Functions
– A Node.js Express server with HTTPS
—
### 🔁 Bonus: If you're deploying a `dist/` Vue build on Firebase, here's what `__redirects` *can* do:
/* /index.html 200
This allows Vue Router to handle SPA routing.
But again, it **won’t help for cross-origin HTTP API calls** over HTTPS.
—
### ✅ Final Recommendation:
Use the Firebase Cloud Function proxy as mentioned in the previous message. It’s the most secure and seamless method to:
– Stay on HTTPS
– Avoid CORS and Mixed Content issues
– Keep your frontend-only Vue project lightweight
Let me know — I can help you copy-paste a ready-made `functions/` setup if needed!
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
import vueDevTools from 'vite-plugin-vue-devtools'
import nightwatchPlugin from 'vite-plugin-nightwatch'
// https://vite.dev/config/
export default defineConfig({
plugins: [
vue(),
vueJsx(),
vueDevTools(),
nightwatchPlugin(),
],
server: {
port: 5185,
strictPort: true,
origin: 'http://localhost:5185',
watch: {
ignored: ['**/node_modules/**', '**/vendor/**'],
usePolling: true,
},
proxy: {
'/api': {
target: 'http://ec2-51-20-60-238.eu-north-1.compute.amazonaws.com/api',
changeOrigin: true,
rewrite: (path) => path.replace(/^/api/, ''),
},
},
},
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
},
},
})
—
### 🔥 Why It Still Fails in Production (Firebase Hosting):
Once you deploy your Vue app (e.g., to Firebase Hosting), the Vite dev server is **no longer running**, and therefore the proxy is **gone**.
So:
– ✅ In local dev:
Request to `https://localhost:5185/api/send-otp` → Vite proxy → `http://ec2…/api/send-otp` ✅
– ❌ In production (on Firebase):
Request to `https://your-app.web.app/api/send-otp` → No proxy → Browser tries to reach `http://…` → ❌ **Mixed Content error**
—
### ✅ Real Fix: You Need a Production-Accessible Proxy (Not Vite Dev Proxy)
Here are your options again:
#### ✅ 1. **Firebase Cloud Functions** (best with Firebase Hosting):
– Secure
– Works with your current stack
– No mixed content
➡️ [Scroll up for full setup](#user-content-🔥-Workaround:-Use-a-Secure-Proxy-on-Firebase-Hosting-(or-any-HTTPS-server))
—
#### ✅ 2. **Host your own HTTPS reverse proxy**
If you want full control:
– Spin up **another EC2 instance**
– Set up **NGINX reverse proxy with HTTPS (via Let's Encrypt)**
– Proxy `/api/send-otp` → `http://ec2-your-ip/api/send-otp`
—
#### ❌ 3. **Using Vite's Proxy in Production** is not possible
Vite's `server.proxy` only runs locally during development. It does **not** affect your production build (`vite build` / `dist/`).
—
### ✅ Recommendation for You
Stick with **Firebase Functions as a proxy**, since you're:
– Already using Firebase Hosting
– Unable to enable HTTPS directly on EC2
– Using only frontend Vue
—
If you want, I can:
– Generate a ready-made Firebase Cloud Function setup zip
– Show how to call it from your Vue app
– (Optional) Suggest a Netlify/Vercel alternative if you're open
Let me know!