88 getFirestore ,
99} from 'firebase/firestore'
1010import {
11+ getCurrentInstance ,
1112 getCurrentScope ,
1213 isRef ,
1314 onScopeDispose ,
@@ -31,6 +32,7 @@ import {
3132 _Nullable ,
3233 _RefWithState ,
3334} from '../shared'
35+ import { getInitialValue } from '../ssr/initialState'
3436import { addPendingPromise } from '../ssr/plugin'
3537import { firestoreUnbinds } from './optionsApi'
3638import {
@@ -51,6 +53,12 @@ export interface _UseFirestoreRefOptions extends FirestoreRefOptions {
5153 * Use the `target` ref instead of creating one.
5254 */
5355 target ?: Ref < unknown >
56+
57+ /**
58+ * Optional key to handle SSR hydration. **Necessary for Queries** or when the same source is used in multiple places
59+ * with different converters.
60+ */
61+ ssrKey ?: string
5462}
5563
5664/**
@@ -68,14 +76,16 @@ export function _useFirestoreRef(
6876) {
6977 let _unbind : UnbindWithReset = noop
7078 const options = Object . assign ( { } , firestoreOptions , localOptions )
79+ const initialSourceValue = unref ( docOrCollectionRef )
7180
81+ const data = options . target || ref < unknown | null > ( )
82+ // set the initial value from SSR even if the ref comes from outside
83+ data . value = getInitialValue ( 'f' , options . ssrKey , initialSourceValue )
7284 // TODO: allow passing pending and error refs as option for when this is called using the options api
73- const data = options . target || ref < unknown | null > ( options . initialValue )
7485 const pending = ref ( true )
7586 const error = ref < FirestoreError > ( )
7687 // force the type since its value is set right after and undefined isn't possible
7788 const promise = shallowRef ( ) as ShallowRef < Promise < unknown | null > >
78- let isPromiseAdded = false
7989 const hasCurrentScope = getCurrentScope ( )
8090 let removePendingPromise = noop
8191
@@ -112,12 +122,6 @@ export function _useFirestoreRef(
112122 )
113123 } )
114124
115- // only add the first promise to the pending ones
116- if ( ! isPromiseAdded && docRefValue ) {
117- // TODO: is there a way to make this only for the first render?
118- removePendingPromise = addPendingPromise ( p , docRefValue )
119- isPromiseAdded = true
120- }
121125 promise . value = p
122126
123127 p . catch ( ( reason : FirestoreError ) => {
@@ -136,6 +140,12 @@ export function _useFirestoreRef(
136140 bindFirestoreRef ( )
137141 }
138142
143+ // only add the first promise to the pending ones
144+ // TODO: can we make this tree shakeable?
145+ if ( initialSourceValue ) {
146+ removePendingPromise = addPendingPromise ( promise . value , initialSourceValue )
147+ }
148+
139149 // TODO: SSR serialize the values for Nuxt to expose them later and use them
140150 // as initial values while specifying a wait: true to only swap objects once
141151 // Firebase has done its initial sync. Also, on server, you don't need to
@@ -145,9 +155,11 @@ export function _useFirestoreRef(
145155 // TODO: warn else
146156 if ( hasCurrentScope ) {
147157 onScopeDispose ( unbind )
148- // wait for the promise during SSR
149- // TODO: configurable
150- onServerPrefetch ( ( ) => promise . value )
158+ if ( getCurrentInstance ( ) ) {
159+ // wait for the promise during SSR
160+ // TODO: configurable
161+ onServerPrefetch ( ( ) => promise . value )
162+ }
151163 }
152164
153165 // TODO: rename to stop
0 commit comments