我遵循以下课程:https://firebase.google.com/docs/functions/callable#java_2我不能调用我的函数。然而,我可以调用触发函数:
在index.json 中
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
//firebase.functions().useFunctionsEmulator('http://localhost:5000') I don't know if i need to use that
//and don't find the path of the firebase module
exports.addMessage = functions.https.onCall((data, context) => {
console.log("addMessage call");
const text = data.text;
const uid = context.auth.uid;
const name = context.auth.token || null;
const picture = context.auth.token.picture || null;
const email = context.auth.token.email || null;
// Checking attribute.
if (!(typeof text === 'string') || text.length === 0) {
// Throwing an HttpsError so that the client gets the error details.
throw new functions.https.HttpsError('invalid-argument', 'The function must be called with ' +
'one arguments "text" containing the message text to add.');
}
// Checking that the user is authenticated.
if (!context.auth) {
// Throwing an HttpsError so that the client gets the error details.
throw new functions.https.HttpsError('failed-precondition', 'The function must be called ' +
'while authenticated.');
}
// Saving the new message to the Realtime Database.
const sanitizedMessage = sanitizer.sanitizeText(text); // Sanitize the message.
return admin.database().ref('/messages').push({
text: sanitizedMessage,
author: { uid, name, picture, email },
}).then(() => {
console.log('New Message written');
// Returning the sanitized message to the client.
return { text: sanitizedMessage };
})
});
在Android Studio(java(中:
public class MainActivity extends AppCompatActivity {
private final static String TAG = "DebugTest";
private DatabaseReference mRef ;
private FirebaseFunctions mFunctions;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button clickBtn = findViewById(R.id.clickBtn);
// WARNING: firebase emulators
mRef = FirebaseDatabase
.getInstance("http://10.0.2.2:9000?ns=my-firebase-application-xxxxx")
.getReference();
mFunctions = FirebaseFunctions.getInstance("http://10.0.2.2:9000?ns=my-firebase-application-xxxx");
clickBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
addMessage("salut les copains")
.addOnCompleteListener(new OnCompleteListener<String>() {
@Override
public void onComplete(@NonNull Task<String> task) {
Log.d(TAG,"onComplete call");
if (!task.isSuccessful()) {
Exception e = task.getException();
if (e instanceof FirebaseFunctionsException) {
FirebaseFunctionsException ffe = (FirebaseFunctionsException) e;
FirebaseFunctionsException.Code code = ffe.getCode();
Object details = ffe.getDetails();
Log.d(TAG,"problème dans appelle de la fonction addMessage: n " + code.toString());
}
// ...
}
// ...
}
});
}
});
}
private Task<String> addMessage(String text) {
// Create the arguments to the callable function.
Map<String, Object> data = new HashMap<>();
data.put("text", text);
data.put("push", true);
return mFunctions
.getHttpsCallable("addMessage")
.call(data)
.continueWith(new Continuation<HttpsCallableResult, String>() {
@Override
public String then(@NonNull Task<HttpsCallableResult> task) throws Exception {
// This continuation runs on either success or failure, but if the task
// has failed then getResult() will throw an Exception which will be
// propagated down.
String result = (String) task.getResult().getData();
Log.d(TAG, "result going to be send");
return result;
}
});
}
}
我在我的Android控制台中有这个:
D/DebugTest: onComplete call
D/DebugTest: problème dans appelle de la fonction addMessage:
INTERNAL
所以(在ContinueWith中(不工作或不被调用。
我没有任何类似";addMessage调用";在firebase模拟器中。。。
有人有任何想法。
PS:我不知道如何找到调用firebase.functions((的模块。useFunctionsSimulator('http://localhost:5000'(
请注意,当您在开发中使用移动设备时,您需要指示firebase从设备的本地ip开始。看见https://github.com/firebase/firebase-tools/issues/1943#issuecomment-581754837但是,当您使用计算机的模拟器时,它不应该返回内部错误。我认为他们应该在返回的错误中添加更多的数据。
有人设法弄清楚这里的问题是什么吗?我在安卓系统中使用Kotlin:
functions = FirebaseFunctions.getInstance()
functions.useEmulator("10.0.2.2", 5001)
并且我也得到了一个内部错误。
我在使用Flutter应用程序调用模拟器中的函数时遇到了类似的问题。
我的每个环境都有多个Firebase项目,因此当我在应用程序中初始化Firebase时,我会根据环境提供FirebaseOptions
。FirebaseOptions
中有一个projectId
参数,它与Firebase控制台中的项目名称相匹配。
我发现,当调用模拟器中的函数时,它并没有像我预期的那样使用projectId
参数中的项目名称,而是使用了在Flutter应用程序中初始化Firebase时使用的FirebaseApp
的名称。由于我没有提供名称,它试图调用一个名为[Default]
的项目,但该项目并不存在。当我将应用程序初始化为与projectId
同名时,内部错误消失了。
Firebase.initializeApp({
name: 'name_of_my_project',
options: FirebaseOptions(),
});
还要注意,在命名应用程序后,在任何Firebase服务上调用instance
都需要更新为instanceFor
,因为instance
将始终尝试获取名为[Default]
的应用程序。示例:
final auth = FirebaseAuth.instanceFor(app: Firebase.apps.first);
@Ben的回答让我明白了为什么在使用iOS模拟器后在真正的iPad上测试ReactNative应用程序时会出现这个错误。当调用第一个函数时,我收到了一个模糊的错误。
我发现用旧的命令firebase serve --only functions -o 0.0.0.0
启动模拟器是有效的,但新的firebase emulators:start --only functions
没有。
这是因为-o参数指示模拟器在所有可用的网络接口上托管,在我的情况下,这些接口包括localhost
、127.0.0.1
和192.168.1.107
。我的iPad上的应用程序需要配置为连接到外部LAN IP 192.168.1.107
上的模拟器(因为localhost
或127.0.0.1
将是它自己的内部地址(。
";firebase仿真器";命令没有-o选项,所以当您启动它时,模拟器只在"上运行;localhost";默认情况下,因此LAN IP不绑定到服务器。
解决方案(除了使用旧的"serve"命令(是配置firebase.json文件:
"emulators": {
"functions" : {
"host": "0.0.0.0"
}
}
还要注意,他们将默认端口从5000("firebase serve"(更改为5001("firebaseemulators"(,因此请确保您的客户端配置正确例如,对我来说,在ReactNative中,我的靴子里有这个:
if(__DEV__){
console.warn('NOTICE: Firebase is using local EMULATORS in __DEV__ environment')
connectFunctionsEmulator(fbFunctions , '192.168.1.107', 5001)`
}