7

I have a collection of firestore documents which contain an array of reference objects, referencing documents found in another firestore collection. When i attempt to fetch a document and convert it to JSON data i get an error : "TypeError: Converting circular structure to JSON". The issue seems to be with the type of the firestore reference? Im new to typescript and am not sure what the issue is as everything works when i exclude the array of references. (Also the references are not actually circular, they reference completely separate documents that are not related)

Here is the code used to get the document

interface PlaylistData {
    name: String
    description: String
    coverImage: String
    tracks: [FirebaseFirestore.DocumentReference]
} 

export const getPlaylist = functions.https.onRequest((request, response) => {
    admin.firestore().collection("playlists")
    .doc('test').get()
    .then(function (snapshot){
        let data = <PlaylistData>snapshot.data()
        console.log(data)
        response.send(data)
    })
    .catch(error => { 
        console.log(error)
        response.status(500).send("ERROR")
    });
});

2 Answers 2

4

You will have to process that data object to remove or convert the document references before passing it to send(). The DocumentReference objects have an internal structure that can't be effectively (or efficiently) serialized. Consider instead just serializing a string that can be used to reconstitute the reference on the client. I suggest simply using its path string property for that. On the client side, you can pass that string to firestore.document() or firestore.doc() to build up a local DocumentReference object again.

Sign up to request clarification or add additional context in comments.

2 Comments

This solved my issue. I used "data.tracks.path" after declaring data to get the path as a string and then stored the path as a string. thank you
The only issue I see about this is that you are likely doubling your document reads (one in the backend and one on the client. Maybe not a big issue depending on how often you use this pattern but it can be if this becomes common and over a large number of requests. One more issue in the areas of security. For example, if you are placing the query in the backend for secured data reasons then you might expose data you wouldn't want the user to see. Honestly, I wonder why Google hasn't created some method to JSON DocumentData class.
0

Maybe this won't work in all solutions but it works for me so far...

Obviously this is a single instance of DocumentData but you should be able to adapt to other scxenarios

const companyDocumentSnapShot2 = await db.doc(<document path>).get()

const companyDocumentDocumentData2 = companyDocumentSnapShot2.data() as FirebaseFirestore.DocumentData
            
return JSON.stringify(companyDocumentDocumentData2)

then on the client I use Moshi (Android) to convert the JSON to a class)

val moshi = Moshi.Builder().build()
val jsonAdapter = moshi.adapter(CompanyRecord::class.java)
val instance = jsonAdapter.fromJson(jsonString)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.