How I Built a Mood‑Tracking Mini‑Program with Fuzzy Location, Backend Reverse Geocoding, and Manual Map Selection

This article details the step‑by‑step development of a WeChat mini‑program that adds location‑based check‑ins, covering fuzzy location retrieval, moving reverse‑geocoding to the backend for key protection, the failed attempt at precise GPS, and the final hybrid approach of fuzzy auto‑location combined with manual map point selection.

Tech Musings
Tech Musings
Tech Musings
How I Built a Mood‑Tracking Mini‑Program with Fuzzy Location, Backend Reverse Geocoding, and Manual Map Selection

Background

The "Mood Diary" WeChat mini‑program records daily moods and needed a geographic check‑in feature, prompting the author to document the implementation challenges.

Phase 1: Fuzzy Location

Without a privacy statement, only wx.getFuzzyLocation (exposed as uni.getFuzzyLocation in uni‑app) could be used, returning only latitude and longitude. The coordinates lack address details, requiring backend reverse‑geocoding.

uni.getFuzzyLocation({
  type: 'gcj02',
  success: (pos) => {
    // pos = { latitude: 39.90, longitude: 116.40 }
    // only coordinates, no city/district text
    // need backend geocode API → "Beijing City, Chaoyang District, Wangjing Street"
  }
})

Limitation: Coordinates are coarse and may deviate noticeably, making precise map markers difficult.

Phase 2: Front‑end Direct Map SDK

After obtaining coordinates, the author initially integrated the Tencent Map JS SDK ( qqmap-wx-jssdk) on the front end to perform reverse‑geocoding.

import QQMapWX from 'qqmap-wx-jssdk'

const qqmap = new QQMapWX({
  key: import.meta.env.VITE_TENCENT_MAP_KEY as string,
})

uni.getLocation({
  type: 'gcj02',
  success: (pos) => {
    qqmap.reverseGeocoder({
      location: { latitude: pos.latitude, longitude: pos.longitude },
      success: (res) => {
        const addr = res.result.address
        const city = res.result.address_component.city
      }
    })
  }
})

Problem: The map API key is exposed in the client bundle, posing a significant security risk.

Phase 3: Moving Reverse Geocoding to the Backend

To hide the map service key, the reverse‑geocoding call was shifted to a backend endpoint that invokes the Tencent Map WebService API using a server‑side key.

async fn geocode(query, config) -> Result<HttpResponse> {
  // call Tencent Map WebService API, key stored in backend env variable
  let resp = client.get("https://apis.map.qq.com/ws/geocoder/v1/")
        .query(&[("location", format!("{},{}", lat, lng)), ("key", config.tencent_map_key)])
        .send().await?;
  // ...
}

Benefit: The map provider key remains only on the server; the front end never sees it. The trade‑off is an extra network request.

Phase 4: Attempting Precise Location

The author tried to request high‑accuracy GPS via wx.getLocation:

uni.getLocation({
  type: 'gcj02',
  isHighAccuracy: true, // GPS‑level precision
  success: (pos) => {
    // backend reverse‑geocode → "Beijing City, Chaoyang District, Jianguo Road 93"
  }
})

Review Result: Repeated submissions were rejected. Community sources indicated that personal developers face strict review for location‑heavy features, and a mood‑tracking app does not qualify as a “strong location‑dependent” scenario, making getLocation permission virtually unattainable.

Phase 5 (Current): Fuzzy Location + Manual Selection

Since precise GPS was infeasible, a compromise was adopted: if automatic fuzzy positioning is inaccurate, allow the user to manually adjust the point using wx.chooseLocation, which passes review more easily.

Current workflow:

用户点击“添加位置"
    ├── 自动定位 → getFuzzyLocation(返回经纬度)→ 后端 geocode API 逆地理编码 → 地址文本
    └── 手动选择 → chooseLocation → 地图选点,直接返回坐标 + 地址

Automatic positioning: Uses getFuzzyLocation to obtain coordinates; backend reverse‑geocoding returns an address such as "Nanjing City, Confucius Temple Gate".

Manual selection: Users pick a precise spot on the map via chooseLocation, which is considered user‑initiated and faces a lenient review.

The data model stores latitude and longitude as nullable fields; successful automatic or manual positioning writes the values, while failures or cancellations leave them null.

interface MoodRecord {
  location: string // address text (auto: backend reverse‑geocode; manual: chooseLocation output)
  locationCity: string // city name
  latitude: number | null // null if positioning fails or is cancelled
  longitude: number | null
}
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

WeChat Mini Programreverse geocodinguni-appgeolocationchooseLocation
Tech Musings
Written by

Tech Musings

Capturing thoughts and reflections while coding.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.