documentReference.data(as: ) not available anymore in Firestore? - firebase

I'm trying to access the documentReference.data(as: ) but it seems like it wouldn't show on my end. I was wondering if this method is deprecated? if so is there any alternative method I can use to map a document reference to a Swift type.
Here's a screenshot of my code:
documentReference.data(as: ) not showing
What I'm try to do is something like this.
func fetchOccupants() async throws -> [Occupant] {
let snapshot = try await occupantsRef.getDocuments()
return snapshot.documents.compactMap { document in
try? document.data(as: Occupants.self)
}
}

I figured it out.
Apparently, at some point this method was moved to a separate module FirebaseFirestoreSwift (or maybe it was always there, I might be wrong).
Import this module and the method data(as:with:decoder:) becomes available:
import FirebaseFirestoreSwift
It's also mentioned on the documentation page about Codable: Map Cloud Firestore data with Swift Codable.

After a few days of testing and reading some documentation I finally solved it. It seems like using Cocoapods to add FirebaseFirestoreSwift is not working, so I tried using Swift Package Manager instead since it's more updated Package Manager for Swift.
Following this method works for me link

Related

Fetch error on Office Script (Excel on web)

I am trying to call an external API from an Excel on web. However, I am stuck on trying to get the result from the fetch call. I am even using the Office doc example to make sure
From an Excel, click on Automate to create a new script
async function main(workbook: ExcelScript.Workbook): Promise<void> {
let fetchResult = await fetch('https://jsonplaceholder.typicode.com/todos/1');
let json = await fetchResult.json();
}
I keep on getting the following message (at the fetchResult.json() call)
"Office Scripts cannot infer the data type of this variable or inferring it might result in unexpected errors. Please annotate the type of the variable to avoid this error. You can also use the Quick fix option provided in the editor to auto fill the type based on the usage. Quick Fix can be accessed by right clicking on the variable name and selecting Quick Fix link."
When running the Chrome inspector, the API request seems to be on hold "CAUTION: request is not finished yet"
PS: I am not the Office administrator and is not reachable right now, but hoping this is not a problem with my user or the Office account configuration
Any idea what the problem might be?
Thanks!
"any" types not being allowed in OfficeScript is by design. We think any types in general can lead to developer errors. I understand it can be hard to declare types – but these days most popular APIs provide you the interface (or d.ts) that you can use.
Secondly, there are tools such as https://quicktype.io/typescript where you can type in your sample JSON and it’ll give you the full interface which you can then declare in your code using interface keyword.
See this code for example: https://github.com/sumurthy/officescripts-projects/blob/main/API%20Calls/APICall.ts
You don’t need to declare all properties – only the ones you’ll use.
It’s more up-front work – but in the end the quality is better.
Adding an interface definition for the expected JSON type fixed the problem for me.
interface Todo {
userId: number;
id: number;
title: string;
completed: boolean
}
async function main(workbook: ExcelScript.Workbook): Promise<void> {
let fetchResult = await fetch('https://jsonplaceholder.typicode.com/todos/1');
let json: Todo = await fetchResult.json();
console.log(json);
}
You may need to define a different interface if the Web API you're calling returns different data structure.

getServerSideProps and mysql (RowDataPacket)

I'd like to do server side rendering with Next.js using the getServerSideProps method like explained in the docs.
The data should come from a database, so I'm using the mysql package. This results in the following error:
Error serializing `.assertions[0]` returned from `getServerSideProps` in "/assertion". Reason: `object` ("[object Object]") cannot be serialized as JSON. Please only return JSON serializable data types.
I think the reason for this is, because the query method from mysql returns special objects (RowDataPacket). The result that I'd like to pass to getServerSideProps looks like this when logged:
[ RowDataPacket { id: 1, title: 'Test' } ]
I can fix this error by wrapping the result with JSON.parse(JSON.stringify(result)) but this seems very odd to me.
So, my simple question is: How to use mysql.query and getServerSideProps correctly?
Or might this be an issue that should be addressed by Next.js?
Thank you
I've run into this issue myself. When I had the issue it wasn't related to MySQL. The problem is getServerSideProps() expects you to return a "JSON serializable data type" which basically means a Plain ol' JavaScript Object (POJO).
To fix it, simply create a new POJO to return. A few ways you can go are:
// using spread operator to create new object
const plainData = {
...queryResult
}
// recreating the object with plucked props
const plainData = {
title: queryResult.title,
content: queryResult.content
}
// data conversion (wax-on wax-off)
const plainData = JSON.parse(JSON.stringify(queryResult))
Your specific data is in an array so your simplest solution is the wax-on wax-off since it will support arrays. Otherwise you've got to map over it.
why tho?
You can see your object has RowDataPacket attached to it. This means it's an instance of RowDataPacket and NextJS doesn't allow any instances unless it strictly equals the Object.prototype (see related code)
This seems weird, but they have already described why it's necessary in a Github Issue. TL;DR dates cause issues client-side when the page hydrates.

Running WebAssembly on Google Apps Script

I am attempting to run WebAssembly on the new V8 Google Apps Script runtime, and it appears to be supported, however it seems that async functions are terminated after they return a Promise.
let wasm= new Uint8Array([/* snip */]).buffer
function add(a,b) {
return((async()=>{
console.log("running function...")
results=await WebAssembly.instantiate(wasm)
return results.instance.exports.add(a,b)
})());
}
function test(){
add(2,3).then(console.log).catch(console.error)
}
when I run test "running function..." is logged, then nothing. No errors, no results. I have confirmed that WebAssembly.instantiate returns a Promise.
Does anyone know what is going on, or is this something to ask Google about?
Update:
Created a issue at https://issuetracker.google.com/issues/153828715
Asynchronous functionalities don't seem to be fully supported in V8 yet. There is actually an open Issue Tracker regarding this. You can click the star on the top left of the page to keep track of this issue.
In any case, please be aware that there is no explicit statement in the official documentation referring to the availability of these functionalities in V8. It just states that you can use keywords like async in your code, but it doesn't mention what functionality you will get if you use that.
Reference:
Issue Tracker: Async with V8 is not implemented as async / concurrent; documentation could be improved
V8 Runtime Overview: Improved function detection
Refactored the sample script you provided on issue tracker and got it to work from the GAS editor (maybe Google changed something since you've posted this issue). GAS is synchronous but you can still use async/await as follows:
async function testWasm() {
let bytes = new Uint8Array([0,97,115,109,1,0,0,0,1,7,1,96,2,127,127,1,127,3,2,1,0,7,7,1,3,97,100,100,0,0,10,9,1,7,0,32,0,32,1,106,11,0,28,4,110,97,109,101,1,6,1,0,3,97,100,100,2,13,1,0,2,0,3,108,104,115,1,3,114,104,115]);
let {
instance: {
exports: {
add
}
}
} = await WebAssembly.instantiate(bytes);
console.log(add(2,3));
}

Using .numChildren() in AngularFire

I'm trying to use .numChildren() in AngularFire, but not sure I'm doing it correctly.
function getServiceProviders(serviceId) {
var serviceProviders = ref.child('services').child(serviceId).child('providers');
return serviceProviders.numChildren();
}
I'm getting the following error:
TypeError: e.numChildren is not a function
Not sure if this is due to me using Browserify, or I'm just trying to access numChildren incorrectly.
Any help is appreciated. Thanks in advance!
Your code snippet doesn't use AngularFire, it only uses the Firebase JavaScript SDK. Although your project undoubtedly uses AngularFire, it doesn't relate to this question.
When you look at the documentation for the .child() method in the Firebase JavaScript SDK, you'll see that it returns a Firebase reference. And if you look further into that class, you should notice that it doesn't have a numChildren method.
numChildren is only available on a DataSnapshot object, which you get in any of the on(... event handlers.
So:
serviceProviders.on('value', function(snapshot) {
console.log(snapshot.numChildren());
}
Since the snapshot will be loaded asynchronously, you cannot return the number of children from getServiceProviders. See my answer to this question for a broader explanation of that: Asynchronous access to an array in Firebase

How do I return an Array from grails / jdo to Flex

this seems really simple but I haven't gotten this to work. I am building my app with grails on google app engine. This pretty much requires you to use JDO.
I am making an HTTP call from flex to my app. The action that I am calling on the grails end looks like so
def returnShowsByDate = {
def query = persistenceManager.newQuery( Show )
def showInstanceList = query.execute()
return (List<Show>) showInstanceList
}
I have tried just returning "hello from grails" and that works just fine. I have alos tried the following
return showInstanceList
the JDO docs say the query.execute() returns a collection. Why I cant just return that to Flex I have no clue.
Any thoughts?
after playing around with this some more I was able to get a result event back by have grails convert the object to JSON or XML
wish I could just return a damn ArrayList. That Would be better but oh well.
OK so I found the fundamental problem and I am answering my own question.
I noticed that I got a fault event when using the JSON stuff too, so I launched a browser and went to the list view that grails provided. Then I requested data from Flex and it worked.
Long story short persistenceManager was null if I didn't go to the html view first so in my method that is being called from Flex I added the following.
if(!persistenceManager)
def persistenceManager
all works well now.

Resources