Firebase文档访问方法及Flutter项目中视频ID存储、获取与子集合创建技术问题咨询
我来帮你逐个拆解这三个Firebase相关的问题,都是日常开发中很常见的场景,咱们一步步来搞定:
1. 如何将视频的真实ID(Firebase自动生成的唯一ID)保存到Firebase?
你当前用集合长度生成ID的方式有个隐患:如果多个用户同时上传视频,大家拿到的集合长度可能重复,导致文档ID冲突。Firebase提供了自动生成唯一文档ID的方法,只需要在创建文档时不传入自定义ID,Firebase会帮你生成一个全局唯一的字符串ID。
修改后的代码如下:
uploadVideo() async { setState(() { isuploading = true; }); try { var firebaseuseruid = FirebaseAuth.instance.currentUser!.uid; DocumentSnapshot userdoc = await FirebaseFirestore.instance .collection('meinprofilsettings') .doc(firebaseuseruid) .get(); // 关键:创建一个自动生成ID的文档引用 final videoDocRef = FirebaseFirestore.instance.collection('videos').doc(); // 获取Firebase自动生成的唯一ID final videoId = videoDocRef.id; // 用这个唯一ID上传视频和预览图 String videourl = await uploadvideotostorage(videoId); String previewimage = await uploadimagetostorage(videoId); // 向自动生成ID的文档中写入数据 await videoDocRef.set({ 'username': userdoc.data()!['username'], 'uid': firebaseuseruid, 'profilepic': userdoc.data()!['url'], 'id': videoId, // 保存真实的文档ID 'likes': [], 'commentcount': 0, 'sharecount': 0, 'hashtag1': hashtagcontroller.text, 'hashtag2': hashtagcontroller2.text, 'hashtag3': hashtagcontroller3.text, 'videourl': videourl, 'previewimage': previewimage, 'ratings': [], }); Navigator.pop(context); } catch (e) { print(e.toString()); } finally { setState(() { isuploading = false; }); } }
这里的核心是FirebaseFirestore.instance.collection('videos').doc(),调用不带参数的doc()会返回一个带有自动生成ID的文档引用,通过videoDocRef.id就能拿到这个唯一ID,用来替换你之前的"Video $length"。
2. 视频ID创建完成后,如何获取并调用该ID?
其实在创建文档引用的时候,你已经能拿到这个ID了——就是上面代码里的videoId变量。你可以在整个上传流程中直接复用这个变量:比如上传存储、写入文档数据,甚至后续跳转到视频详情页时传递这个ID。
如果是事后需要从已有的文档中获取ID,比如查询视频列表时,每个DocumentSnapshot对象都有id属性:
// 示例:获取所有视频文档并打印ID var alldocs = await FirebaseFirestore.instance.collection('videos').get(); for (var doc in alldocs.docs) { print('视频ID:${doc.id}'); print('视频数据:${doc.data()}'); }
3. 如何使用该ID创建新集合(如videoed)并存储数据?
Firebase的集合是懒加载的,不需要提前手动创建——当你向某个集合添加第一个文档时,Firebase会自动创建这个集合。你可以通过父文档的ID来关联子集合,比如给每个视频文档创建一个videoed子集合,用来存储和这个视频相关的额外数据(比如评论、编辑记录等)。
举个例子,在上传视频成功后,直接用videoId创建videoed集合并写入数据:
// 在uploadVideo函数的try块中,写入完video文档后添加这段代码 await FirebaseFirestore.instance .collection('videos') .doc(videoId) // 用视频的唯一ID定位父文档 .collection('videoed') // 子集合名称:videoed .add({ // 添加一个新文档到子集合 'timestamp': FieldValue.serverTimestamp(), 'action': '视频上传完成', 'operatorUid': firebaseuseruid, // 其他你需要存储的数据 });
如果你需要给子集合的文档也用自定义ID,把add()换成doc('自定义ID').set({...})就行。
另外,你的uploadimagetostorage函数里有个小问题:id=url;这行代码没什么作用,因为参数是按值传递的,修改不会影响外部变量,建议删掉这行。
内容的提问来源于stack exchange,提问作者user15564550

