Load JSON into Firestore - data types - google-cloud-firestore

Native JSON only supports string, number, boolean. Firestore supports additional types - timestamp, geopoint, date/time. How should you format the JSON to load these data types?

Here's some information about supported datatypes: https://firebase.google.com/docs/firestore/manage-data/data-types
As well as an example:
var docData = {
stringExample: "Hello world!",
booleanExample: true,
// Note that numbers can be either integers or floating point
numberExample: 3.14159265,
// JSON representation as RFC 3339 String with timezone Z
// e.g. 1815-12-10T00:00:00.000Z
dateExample: new Date("December 10, 1815"),
arrayExample: [5, true, "hello"],
nullExample: null,
objectExample: {
a: 5,
b: {
nested: "foo"
}
},
// JSON object w/ latitude and longitude keys
geoPointExample: {
latitude: 37.773972
longitude: -122.431297
},
// FIRESTORE GEOPOINT
geoPointExample2: new firebase.firestore.GeoPoint(37.7739,-122.4312)
// Blobs are base64 encoded strings
blobExample: "RmlyZXN0b3JlIGlzIGF3ZXNvbWUh"
};
More info on protobuf to JSON is available here: https://developers.google.com/protocol-buffers/docs/proto3#json

Related

How to format Yup date() to brazilian format?

I'm wanting to use yup to validate an input, that is being used as Birthday. By first I added the simple .date() function to the yup shaped object, but it won't accept Brazilian dates, as the format is same as European (dd/MM/YYYY), how do I proceed?
Use .transform() to parse your value with a function passing the following parameters:
value as current Date parsed by yup.
originalValue as the original inputted value (e.g. "01/01/2022").
yup.date().transform((value, originalValue) => {
// Do your parsing structure
return newValue
})
Remember that your newValue must be a Date object since you want to validate a yup.date() type in your form.
You can use this example as solution for you to parse your value to "dd/MM/YYYY" format:
// Input: '10/12/2022'
// yup.object({ [...]
birthday: yup.date().transform((value, originalValue) => {
// originalValue = "10/12/2022"
try {
let date = originalValue.split('/')
// date = ["10", "12", "2022"] <- day, month and year respectively
if (date.length === 3) {
let newDate = `${date[2]}-${date[1]}-${date[0]}`
return new Date(newDate)
}
return null
} catch (e) {
return null
}
}),
// [...] })
// Expected Output: '2022-10-12T00:00:00.000Z'
See yup docs about parsing values using .transform(): Yup Schema Basics - Parsing: Transforms

How to save a CLLocation with Cloudkit JS

I'm using Cloudkit JS to save data to a public database. Its easy to do when the fields are all strings. I'm stuck now trying to figure out how to save data when the field type is a CLLocation. Somehow I need to structure the JavaScript to send both latitude and longitude values.
See the ??? in the code example below;
var new record = { recordType: "Thing",
fields: { name: { value: "My Name" },
description: { value: "My Description" },
location: { ??? }
}
};
Does anyone know how to take the lat and long coordinates and represent them in the code above?
Try passing it like this:
fields: {
location: { value: { latitude: lat, longitude: lng }, type: "LOCATION" }
}
lat and lng are Doubles, not Strings

Swift 4.1 - Cannot convert value of type [Character] to [String]

My code was supporting Swift 3.3 before, now I'm upgrading it to Swift 4.1 using Xcode 9.3. It shows me the following error while trying to build my project.
Here is code for JSON parsing
// MARK: Store JSON initializer
convenience init?(withJSON json: JSON) {
//json mapping
//This is of type [Character] after mapping
let services = json["services"].arrayValue.flatMap({ $0 }).flatMap({ $0.1.stringValue }) //Convert response to 1D array and convert it to array if String
}
Here is that init method which I'm trying to call
//Custom init method
init(id: Int, storeNumber: String, title: String, location: Location, type: String, zip: String, parent: Int, city: String, services: [String], state: String, storePhone: [String], pharmacyPhone: [String], pharmacyFax: [String], workingHours: WorkingHoursString) {
//field with error
//here self.services is of type [String]
self.services = services
}
I'm using
pod 'SwiftyJSON', '3.1.4' For Json parsing.
Error - Cannot convert value of type '[character]' to expected argument
type '[String]'
/* JSON for services is as given
"services":[
[
"Fresh Food"
]
]
*/
print("Services are \(services)")
Services are ["F", "r", "e", "s", "h", " ", "F", "o", "o", "d"]
What could be the simplest solution to fix this?
The same behavior can be observed in the following code:
let services: [[String: Any]?] = [
["service1": "service1-name"],
["service2": "service2-name"]
]
let result = services
.flatMap({ $0 })
.flatMap({ $0.1 as! String })
print(result)
I think this is caused by the multiple changes in String and Dictionary in Swift 4 (String becoming a Collection of characters for example). In the code above the first flatMap merges (flattens) the dictionaries into one dictionary and the second flatMap takes every value as a String and flattens them as a 2D Collection of Character.
I think you want something like this:
let result = services
.compactMap { $0 } // remove nil dictionaries
.flatMap { // take all dictionary values as strings and flatten them to an array
$0.values.map { $0.stringValue }
}
print(result)
This line gives an array of strings, expected results
let services = json["services"]
.arrayValue
.flatMap { $0.arrayValue }
.map { $0.stringValue }

How to get unicode code point(s) representation of character/string in Swift?

As a generic solution, how can we get the unicode code point/s for a character or a string in Swift?
Consider the following:
let A: Character = "A" // "\u{0041}"
let Á: Character = "Á" // "\u{0041}\u{0301}"
let sparklingHeart = "💖" // "\u{1F496}"
let SWIFT = "SWIFT" // "\u{0053}\u{0057}\u{0049}\u{0046}\u{0054}"
If I am not mistaking, the desired function might return an array of strings, for instance:
extension Character {
func getUnicodeCodePoints() -> [String] {
//...
}
}
A.getUnicodeCodePoints()
// the output should be: ["\u{0041}"]
Á.getUnicodeCodePoints()
// the output should be: ["\u{0041}", "\u{0301}"]
sparklingHeart.getUnicodeCodePoints()
// the output should be: ["\u{1F496}"]
SWIFT.getUnicodeCodePoints()
// the output should be: ["\u{0053}", "\u{0057}", "\u{0049}", "\u{0046}", "\u{0054}"]
Any more suggested elegant approach would be appreciated.
Generally, the unicodeScalars property of a String returns a collection
of its unicode scalar values. (A Unicode scalar value is any
Unicode code point except high-surrogate and low-surrogate code points.)
Example:
print(Array("Á".unicodeScalars)) // ["A", "\u{0301}"]
print(Array("💖".unicodeScalars)) // ["\u{0001F496}"]
Up to Swift 3 there is no way to access
the unicode scalar values of a Character directly, it has to be
converted to a String first (for the Swift 4 status, see below).
If you want to see all Unicode scalar values as hexadecimal numbers
then you can access the value property (which is a UInt32 number)
and format it according to your needs.
Example (using the U+NNNN notation for Unicode values):
extension String {
func getUnicodeCodePoints() -> [String] {
return unicodeScalars.map { "U+" + String($0.value, radix: 16, uppercase: true) }
}
}
extension Character {
func getUnicodeCodePoints() -> [String] {
return String(self).getUnicodeCodePoints()
}
}
print("A".getUnicodeCodePoints()) // ["U+41"]
print("Á".getUnicodeCodePoints()) // ["U+41", "U+301"]
print("💖".getUnicodeCodePoints()) // ["U+1F496"]
print("SWIFT".getUnicodeCodePoints()) // ["U+53", "U+57", "U+49", "U+46", "U+54"]
print("🇯🇴".getUnicodeCodePoints()) // ["U+1F1EF", "U+1F1F4"]
Update for Swift 4:
As of Swift 4, the unicodeScalars of a Character can be
accessed directly,
see SE-0178 Add unicodeScalars property to Character. This makes the conversion to a String
obsolete:
let c: Character = "🇯🇴"
print(Array(c.unicodeScalars)) // ["\u{0001F1EF}", "\u{0001F1F4}"]

How to insert a multidimensional array

want to save the data of the following format
{"_ibj_id":"1","url_id":'1',"url":{"0":"http://0.com","1":"http:://1.com"}}
Look at my code,
type db_list struct {
Url_id int
Url map[int]string
}
func list(table *mgo.Collection) {
var doc *goquery.Document
var e error
for i := 1628644; i > 1628643; i-- {
if doc, e = goquery.NewDocument("http://www.120ask.com/list/all/" + strconv.Itoa(i)); e != nil {
panic(e.Error())
}
var save_list db_list
save_list.Url_id = i
save_list.Url = make(map[int]string)
//fmt.Println("%s", doc.Text())
doc.Find(".q-quename").Each(func(n int, s *goquery.Selection) {
href, isTrue := s.Attr("href")
if isTrue {
save_list.Url[n] = href
fmt.Println("%D : %s", n, save_list.Url[n])
}
})
fmt.Println("%D", len(save_list.Url))
//save database
table.Insert(save_list)
}
}
The database will eventually save
Please view the picture in the annex, is to save the format of the data, save the URLvalue of the property 1
You're probably after the JSON Unmarshal function in encoding/json
{"_ibj_id":"1","url_id":'1',"url":{"0":"http://0.com","1":"http:://1.com"}} is technically invalid JSON due to the single-quotes around the url_id value( '1' should be "1") but other than that, it should map nicely to the following struct:
{
id string
url_id string
urls []string
}
But you may need to experiment with the types. According to the docs for the Unmarshal function, it will use the following Go types for each JSON type:
bool, for JSON booleans
float64, for JSON numbers
string, for JSON strings
[]interface{}, for JSON arrays
map[string]interface{}, for JSON objects
nil for JSON null
I'd highly recommend reading Andrew Gerrands Blog Post "JSON and Go".
It's unclear to me exactly what you are trying to do. One thing I notice though, is that in your desired format the keys for Url are string values where as in Go they are integers. You could try changing the type of Url to map[string]string and see if that solves your problem.