尝试从 MongoDB Atlas 检索视频时,React Native 应用程序卡在加载屏幕上

问题描述 投票:0回答:0

我正在使用 React Native 和 Expo 工具链开发一个简单的社交媒体应用程序。该应用程序的主要功能是允许用户上传视频并与他人分享。在“浏览”屏幕上,用户应该能够查看上传的视频。这些视频是从 MongoDB Atlas 数据库检索的,预计将显示在应用程序中。但是,当我加载应用程序时,我被困在加载图标中,并且最终超时。

以下是我的设置的一些详细信息:

视频上传和检索功能由 Express.js 后端服务器处理。 我使用 Multer 中间件来处理 multipart/form-data,并使用 multer-gridfs-storage 引擎使用 GridFS 规范将上传的文件直接存储到 MongoDB。 我能够从手机成功上传视频,并且它们在 MongoDB 数据库中显示为新集合(在“test”数据库内,名为“uploads.files.chunks”和“uploads.files.files”的集合中)。 我可以从我的服务器加载静态文本(“Hello World!”消息),但视频检索不起作用。

我尝试了多种方法来诊断问题,包括:

验证我的服务器正在运行并连接到 MongoDB 通过放置控制台日志确保我的“/api/videos”路线被命中 检查数据库以查看文件是否存在(确实存在) 在浏览器开发者工具中检查网络请求(没有出现)

下面是我的 Express.js 服务器的相关代码:

const express = require('express');
const mongoose = require('mongoose');
const multer = require('multer');
const { GridFsStorage } = require('multer-gridfs-storage');
const Grid = require('gridfs-stream');
const cors = require('cors');
require('dotenv').config();

// Create Express server
const app = express();

// Enable CORS
app.use(cors());

// Database connection
const conn = mongoose.createConnection(process.env.MONGODB_URI, {
  useNewUrlParser: true,
  useUnifiedTopology: true,
});

conn.on('connected', () => {
  console.log('Connected to MongoDB');
});

conn.on('error', (err) => {
  console.error('Failed to connect to MongoDB', err);
});

let gfs;

conn.once('open', () => {
  // Initialize GridFS
  gfs = Grid(conn.db, mongoose.mongo);
  gfs.collection('uploads.files');

  // Add this test query
  conn.db.collection('uploads.files').find().limit(1).toArray((err, docs) => {
    console.log('Test Query executed');
    if (err) {
      console.log('Error executing test query', err);
    } else if (docs.length === 0) {
      console.log('Test query returned no documents');
    } else {
      console.log('Test query returned document:', docs[0]);
    }
  });

  // Start server
  const port = process.env.PORT || 5000;
  app.listen(port, () => {
    console.log(`Server is running on port ${port}`);
  });
});

// Create storage engine
const storage = new GridFsStorage({
  url: process.env.MONGODB_URI,
  options: { useNewUrlParser: true, useUnifiedTopology: true },
  file: (req, file) => {
    return new Promise((resolve, reject) => {
      // Use the _id as the filename
      const filename = new mongoose.Types.ObjectId();
      const fileInfo = {
        filename: filename,
        bucketName: 'uploads.files',
      };
      resolve(fileInfo);
    });
  },
});

const upload = multer({ storage });

// Middleware
app.use(express.json());

// Routes
app.get('/', (req, res) => {
  res.send('Hello World!');
});

app.post('/api/videos', upload.single('video'), (req, res) => {
  console.log('Upload route hit'); 
  console.log('req.body:', req.body);
  console.log('req.file:', req.file);
  // Video uploaded successfully
  res.json({ message: 'Video uploaded successfully' });
});

app.get('/api/videos', (req, res) => {
  console.log('Get videos route hit');
  gfs.files.find().sort({ uploadDate: -1 }).toArray((err, files) => {
    // Check if an error occurred during the database query
    if (err) {
      console.error('Error occurred during database query:', err);
      return res.status(500).json({ message: 'Internal server error' });
    }
    
    // Check if files exist
    if (!files || files.length === 0) {
      console.log('No files exist');
      return res.status(404).json({ message: 'No files exist' });
    }

    // Files exist
    console.log('Files found:', files);
    return res.json(files);
  }).catch(err => console.error('Error executing query:', err));  // Add this line
});

这是我的前端 React Native 应用程序的相关代码:

import React, { useEffect, useState } from 'react';
import { View, Text, ActivityIndicator, StyleSheet } from 'react-native';
import axios from 'axios';
import VideoPlayer from '../components/VideoPlayer';

function Explore() {
  const [videos, setVideos] = useState([]);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    const fetchVideos = async () => {
      try {
        const response = await axios.get('http://localhost:5000/api/videos');
        console.log('Response data:', response.data); // Add this line
        setVideos(response.data);
        setIsLoading(false);
      } catch (err) {
        console.log('Error:', err);  // Add this line
        setError(err.message);
        setIsLoading(false);
      }
    };
  
    fetchVideos();
  }, []);
  

  if (isLoading) {
    return (
      <View style={styles.loadingContainer}>
        <ActivityIndicator size="large" color="#0000ff" />
      </View>
    );
  }

  if (error) {
    return (
      <View style={styles.errorContainer}>
        <Text style={styles.errorText}>Error: {error}</Text>
      </View>
    );
  }

  return (
    <View style={styles.container}>
      {videos.length > 0 ? (
  videos.map(video => (
    <VideoPlayer key={video._id} videoId={video._id} />  // Replace _id with filename if necessary
  ))
) : (
  <Text>No videos found.</Text>
)}
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    backgroundColor: '#ecf0f1',
  },
  loadingContainer: {
    flex: 1,
    justifyContent: 'center',
  },
  errorContainer: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    padding: 20,
  },
  errorText: {
    color: 'red',
    fontSize: 18,
    textAlign: 'center',
  },
});

export default Explore;

当我尝试加载“探索”屏幕时,我只在终端中看到“获取视频路由命中”,而没有其他内容。屏幕继续显示加载图标。

任何帮助将不胜感激,因为我不确定如何从这里继续。甚至 ChatGPT 也对我说“抱歉,我不明白这个”哈哈。

mongodb react-native express expo gridfs
© www.soinside.com 2019 - 2024. All rights reserved.