是否有任何重大变化,我的云功能停止与Flutter网络?

nukf8bse  于 2023-10-22  发布在  Flutter
关注(0)|答案(3)|浏览(124)

我曾经运行过Firebase Cloud Functions。但是在重构了我的整个代码库以使其听起来空安全之后,云函数停止了工作(可悲的是,我无法在时间轴的哪个点重现)。
pubspec.yaml

dependencies:
      flutter:
        sdk: flutter
      firebase_core: ^1.0.2
      firebase_auth: ^1.0.1
      cloud_firestore: ^1.0.4
      cloud_functions: ^1.1.0
      ...

web/index.html

...
  <script src="https://www.gstatic.com/firebasejs/8.6.1/firebase-app.js"></script>
  <script src="https://www.gstatic.com/firebasejs/8.6.1/firebase-functions.js"></script>
  <script src="https://www.gstatic.com/firebasejs/7.19.1/firebase-auth.js"></script>
  <script src="https://www.gstatic.com/firebasejs/7.19.1/firebase-firestore.js"></script>
    
  <script>
    // Your web app's Firebase configuration
    var firebaseConfig = {
      apiKey: "<myApiKey>",
      authDomain: "<my-project>.firebaseapp.com",
      databaseURL: "https://<my-project>.firebaseio.com",
      projectId: "<my-project>",
      storageBucket: "<my-project>.appspot.com",
      messagingSenderId: "<myMessageSenderId>",
      appId: "<myAppId>"
    };
    // Initialize Firebase
    firebase.initializeApp(firebaseConfig);
    firebase.functions().useFunctionsEmulator("http://10.0.2.2:5001");
  </script>
  
  <script src="main.dart.js" type="application/javascript"></script>
</body>
</html>

functions/index.js

const functions = require('firebase-functions');
const admin = require('firebase-admin');
const { UserPropertyValue } = require('firebase-functions/lib/providers/analytics');
admin.initializeApp();

exports.setRoles = functions.https.onCall((data, context) => {
    let userId = null;
    let userCustomClaimsAdmin = false;
    let userCustomClaimsEditor = false;

    // get user and update custom claim
    return admin.auth().getUserByEmail(data.email).then(user => {

        userId = user.uid;
        const currentCustomClaims = (user.customClaims == undefined) ? {} : user.customClaims;
        switch (data.role) {
            case 'admin':
                currentCustomClaims.admin = (data.permission == 'grant') ? true : false;
            break;
            case 'editor':
                currentCustomClaims.editor = (data.permission == 'grant') ? true : false;
            break;
            default:
                return;
        }

        userCustomClaimsAdmin = currentCustomClaims.admin;
        userCustomClaimsEditor = currentCustomClaims.editor;

        return admin.auth().setCustomUserClaims(userId,
            currentCustomClaims
        );
        }).then(() => {
            // Update User record in Firestore
            return admin.firestore().collection("users").doc(userId).update({
                isAdmin: userCustomClaimsAdmin,
                isEditor: userCustomClaimsEditor,
            });
        }).then(() => {
            return {
                message: 'Success'
            }
        })
        .catch(err => {
            console.log(err.toString());
        });
});

最后,我调用函数:

...
   final HttpsCallable setRoleCallable = FirebaseFunctions.instance
        .httpsCallable('setRoles',
            options:
                HttpsCallableOptions(timeout: const Duration(seconds: 10)));
...
              try {
                final HttpsCallableResult result = await setRoleCallable.call(
                  <String, dynamic>{
                    'email': "<emailOfUserToBeChanged>",
                    'role': "<selectedRole>",
                    'permission': "<givenAccess>"
                  },
                );
                print(result.data);
              } on FirebaseFunctionsException catch (e) {
                print('caught firebase functions exception');
                print(e.code);
                print(e.message);
                print(e.details);
              } catch (e) {
                print('caught generic exception');
                print(e);
              }

该调用(本地主机上的仿真函数,10.0.2.2)结束于

caught firebase functions exception
internal
internal
null

在这段时间里,有什么我错过的改变吗?我在Firebase文档中找不到任何关于此主题的内容。
也许这可能是一个小的变化,在某个时候,我还没有认识到..

cfh9epnr

cfh9epnr1#

好吧,云功能的一个主要变化是,你现在必须有付费的Firebase计划才能使用云功能,因为他们遗憾地从免费层中删除了云功能

mfuanj7w

mfuanj7w2#

在Cloud Function中,您不必等待异步操作完成才发送回响应。有关此关键方面的更多详细信息,请参阅doc
棘手的是,它会产生一些“不稳定”的行为(有时有效,有时无效),可以解释如下:

  • 在某些情况下,您的Cloud Function会在异步操作完成之前终止,如上面提到的文档所述。
  • 但是,在某些其他情况下,Cloud Functions平台可能不会立即终止您的CF,从而有足够的时间完成异步操作。

所以你有这样的印象,“云功能停止与Flutter网络工作”,而实际上,有时它的工作和其他一些时候不.
此外,注意setCustomUserClaims()方法返回Promise<void>而不是user,因此您需要为userId和声明保留一组全局变量,以便将其从一个then()块传递到另一个块。
因此,以下内容应该可以做到这一点(未经测试):

exports.setRoles = functions.https.onCall((data, context) => {
    console.log('user to change email: ' + data.email);

    let userId = null;
    let userCustomClaimsAdmin = false;
    let userCustomClaimsEditor = false;

    // get user and update custom claim
    return admin.auth().getUserByEmail(data.email)
        .then(user => {

            userId = user.uid;   //  the setCustomUserClaims() method returns a Promise<void> not a user !!

            const currentCustomClaims = (user.customClaims == undefined) ? {} : user.customClaims;
            switch (data.role) {
                case 'admin':
                    currentCustomClaims.admin = (data.permission == 'grant') ? true : false;
                    break;
                case 'editor':
                    currentCustomClaims.editor = (data.permission == 'grant') ? true : false;
                    break;
                default:
                    return;
                    break;
            }

            // Here you need to adapt the value of userCustomClaimsAdmin and userCustomClaimsEditor
            userCustomClaimsAdmin = ...
            userCustomClaimsEditor = ...

            // See return below !!!!
         
            return admin.auth().setCustomUserClaims(user.uid,
                currentCustomClaims
            );

        })
        .then(() => {
            // See return below  !!!!
            return admin.firestore().collection("users").doc(userId).update({
                isAdmin: (userCustomClaimsAdmin) ? user.customClaims.admin : false,
                isEditor: (userCustomClaimsEditor) ? user.customClaims.editor : false,
            });
        })
        .then(() => {
            return {
                message: 'Success'
            }
        })
        .catch(err => {
            console.log(err.toString());
            // !!!! See the doc: https://firebase.google.com/docs/functions/callable#handle_errors
        });
});
oknrviil

oknrviil3#

我正在开发一个扑翼网项目我使用的是cloud-functions,而不是cloud-functions-web。
在我的main.dart中,缺少使用函数模拟器的指令:

...
Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  FirebaseFunctions.instance
      .useFunctionsEmulator(origin: 'http://localhost:5001'); // this was missing
  runApp(MyApp());
...
}

它曾经工作,因为我已经在我的index.html指令

...
    // Initialize Firebase
    firebase.initializeApp(firebaseConfig);
    firebase.functions().useFunctionsEmulator("http://10.0.2.2:5001");
...

不过,它现在工作。

相关问题