diff --git a/web/components/use-save-shares.ts b/web/components/use-save-shares.ts index bd1ac5a1..9bf3e739 100644 --- a/web/components/use-save-shares.ts +++ b/web/components/use-save-shares.ts @@ -8,6 +8,7 @@ import { import { Bet } from 'common/bet' import { useEffect, useState } from 'react' import { partition, sumBy } from 'lodash' +import { safeLocalStorage } from 'web/lib/util/local' export const useSaveShares = ( contract: FullContract, @@ -39,18 +40,16 @@ export const useSaveShares = ( const noFloorShares = Math.round(noShares) === 0 ? 0 : Math.floor(noShares) useEffect(() => { + const local = safeLocalStorage() // Save yes and no shares to local storage. - const savedShares = localStorage.getItem(`${contract.id}-shares`) + const savedShares = local?.getItem(`${contract.id}-shares`) if (!userBets && savedShares) { setSavedShares(JSON.parse(savedShares)) } if (userBets) { const updatedShares = { yesShares, noShares } - localStorage.setItem( - `${contract.id}-shares`, - JSON.stringify(updatedShares) - ) + local?.setItem(`${contract.id}-shares`, JSON.stringify(updatedShares)) } }, [contract.id, userBets, noShares, yesShares]) diff --git a/web/lib/firebase/fn-call.ts b/web/lib/firebase/fn-call.ts index 72a2a110..3713c4e5 100644 --- a/web/lib/firebase/fn-call.ts +++ b/web/lib/firebase/fn-call.ts @@ -5,6 +5,7 @@ import { User } from 'common/user' import { randomString } from 'common/util/random' import './init' import { functions } from './init' +import { safeLocalStorage } from '../util/local' export const cloudFunction = (name: string) => httpsCallable(functions, name) @@ -48,10 +49,11 @@ export const resolveMarket = cloudFunction< >('resolveMarket') export const createUser: () => Promise = () => { - let deviceToken = window.localStorage.getItem('device-token') + const local = safeLocalStorage() + let deviceToken = local?.getItem('device-token') if (!deviceToken) { deviceToken = randomString() - window.localStorage.setItem('device-token', deviceToken) + local?.setItem('device-token', deviceToken) } return cloudFunction('createUser')({ deviceToken }) diff --git a/web/lib/firebase/users.ts b/web/lib/firebase/users.ts index 4edcddb8..1e316744 100644 --- a/web/lib/firebase/users.ts +++ b/web/lib/firebase/users.ts @@ -27,6 +27,7 @@ import { getValue, getValues, listenForValue, listenForValues } from './utils' import { DAY_MS } from 'common/util/time' import { feed } from 'common/feed' import { CATEGORY_LIST } from 'common/categories' +import { safeLocalStorage } from '../util/local' export type { User } @@ -86,8 +87,9 @@ let createUserPromise: Promise | undefined = undefined const warmUpCreateUser = throttle(createUser, 5000 /* ms */) export function listenForLogin(onUser: (user: User | null) => void) { - const cachedUser = localStorage.getItem(CACHED_USER_KEY) - onUser(cachedUser ? JSON.parse(cachedUser) : null) + const local = safeLocalStorage() + const cachedUser = local?.getItem(CACHED_USER_KEY) + onUser(cachedUser && JSON.parse(cachedUser)) if (!cachedUser) warmUpCreateUser() @@ -106,11 +108,11 @@ export function listenForLogin(onUser: (user: User | null) => void) { // Persist to local storage, to reduce login blink next time. // Note: Cap on localStorage size is ~5mb - localStorage.setItem(CACHED_USER_KEY, JSON.stringify(user)) + local?.setItem(CACHED_USER_KEY, JSON.stringify(user)) } else { // User logged out; reset to null onUser(null) - localStorage.removeItem(CACHED_USER_KEY) + local?.removeItem(CACHED_USER_KEY) createUserPromise = undefined } }) diff --git a/web/lib/util/local.ts b/web/lib/util/local.ts new file mode 100644 index 00000000..0778c0ac --- /dev/null +++ b/web/lib/util/local.ts @@ -0,0 +1,11 @@ +export const safeLocalStorage = () => (isLocalStorage() ? localStorage : null) + +const isLocalStorage = () => { + try { + localStorage.getItem('test') + localStorage.setItem('hi', 'mom') + return true + } catch (e) { + return false + } +}