【问题标题】:Kotlin and Firebase cloud functions update() methodKotlin 和 Firebase 云函数 update() 方法
【发布时间】:2018-07-01 16:42:02
【问题描述】:

我正在使用 Kotlin 为 Firebase 云功能生成 Javascript 代码。

我想调用update 方法,将一些值作为参数传递。在 Kotlin 中,我必须将 Map 作为 update() 的参数传递:

val map = mutableMapOf<String,Int>() //also tried with a Hashmap: same result

//generate some values
for(i in 0 until 3){ 
    map.put("key$i", i)
}
console.log(map.keys.toList().toString()) //log map keys
console.log(map.values.toList().toString()) //log map values

ref.child("values").update(map)

Kotlin 生成该 javascript 代码:

var LinkedHashMap_init = Kotlin.kotlin.collections.LinkedHashMap_init_q3lmfv$;
function main$lambda(event){
    var map = LinkedHashMap_init();
    for (var i = 0; i < 3; i++) {
      map.put_xwzc9p$('key' + i, i);
    }
    console.log(toList(map.keys).toString());
    console.log(toList(map.values).toString());
    ref.child('values').update(map);
}

在我的 Firebase 控制台中,这是 2 个日志的结果。似乎表明地图是正确的:

[key0, key1, key2]
[0, 1, 2]

但 update() 不起作用:函数日志显示该消息:

Error: Reference.update failed: First argument  contains an invalid key (this$AbstractMutableMap) in property 'games.test.values._keys_qe2m0n$_0'.  Keys must be non-empty strings and can't contain ".", "#", "$", "/", "[", or "]"
    at /user_code/node_modules/firebase-admin/node_modules/@firebase/database/dist/cjs/src/core/util/validation.js:139:27
    at Object.exports.forEach (/user_code/node_modules/firebase-admin/node_modules/@firebase/util/dist/cjs/src/obj.js:37:13)
    at Object.exports.validateFirebaseData (/user_code/node_modules/firebase-admin/node_modules/@firebase/database/dist/cjs/src/core/util/validation.js:132:16)
    at /user_code/node_modules/firebase-admin/node_modules/@firebase/database/dist/cjs/src/core/util/validation.js:223:17
    at Object.exports.forEach (/user_code/node_modules/firebase-admin/node_modules/@firebase/util/dist/cjs/src/obj.js:37:13)
    at Object.exports.validateFirebaseMergeDataArg (/user_code/node_modules/firebase-admin/node_modules/@firebase/database/dist/cjs/src/core/util/validation.js:221:12)
    at Reference.update (/user_code/node_modules/firebase-admin/node_modules/@firebase/database/dist/cjs/src/api/Reference.js:140:22)
    at main$lambda (/user_code/index.js:87:25)
    at Object.<anonymous> (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:59:27)
    at next (native)

但最后,如果我手动将 js 代码写入函数,它可以工作:

var map = {}
for (var i = 0; i < 3; i++) {
    map["key"+i] = i
}
ref.child("values").update(map)

问候。

【问题讨论】:

    标签: javascript firebase kotlin google-cloud-functions


    【解决方案1】:

    感谢Doug's answer,我写了那个小sn-p来将一个简单的键/值javascript对象包装到一个Kotlin类型的对象中:

    class JsWrapperMap<K, V> {
        private val map: dynamic = js("({})")
    
        operator fun get(key: K): V = map[key]
        operator fun set(key: K, value: V) {
            map[key] = value
        }
    
        fun toJs(): dynamic = map
    }
    
    /**
     * Returns an empty new [JsWrapperMap]
     */
    fun <K, V> jsMapOf(): JsWrapperMap<K, V> = JsWrapperMap()
    
    /**
     * Returns an empty new [JsWrapperMap] of type <Any, Any>
     */
    fun jsMapOfAny(): JsWrapperMap<Any, Any> = JsWrapperMap()
    

    可以这样使用:

    val map = jsMapOf<String, Int>()
    map["key_0"] = 12
    map["key_1"] = 36
    ref.child("values").update(map.toJs()) 
    

    我愿意接受有关该代码的任何建议 :)

    【讨论】:

      【解决方案2】:

      Kotlin 显然是在通过您对 mutableMapOf 的调用生成 LinkedHashMap

      update() 接受一个 JavaScript 对象,其普通、简单的属性应该用于更新文档。

      我相当肯定,JavaScript 中 LinkedHashMap 的实现有很多对象属性会违反规定的约束,正如您从错误消息中看到的那样。

      您不能简单地将任何类型的对象传递给update()。您需要将只包含您想要的键和值的对象传递给update()。该方法根本不会期望像LinkedHashMap 这样的复杂事物。相反,您需要编写一些可编译为简单 JavaScript 对象的内容。

      也许是this would be helpful to read

      【讨论】:

        猜你喜欢
        • 2017-10-13
        • 2018-09-13
        • 2019-01-18
        • 2020-06-28
        • 2017-07-31
        • 2019-10-17
        • 2019-10-29
        • 2022-09-25
        相关资源
        最近更新 更多